/* java.lang.reflect.Field - reflection of Java fields
- Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2001, 2005, 2008 Free Software Foundation, Inc.
This file is part of GNU Classpath.
package java.lang.reflect;
import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
import gnu.java.lang.reflect.FieldSignatureParser;
+import java.lang.annotation.Annotation;
+
/**
* The Field class represents a member variable of a class. It also allows
* dynamic access to a member, via reflection. This works for both
public final class Field
extends AccessibleObject implements Member
{
- private Class declaringClass;
- private String name;
- private int slot;
-
- private static final int FIELD_MODIFIERS
+ static final int FIELD_MODIFIERS
= Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
| Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
| Modifier.VOLATILE;
+ private FieldSignatureParser p;
+
+ VMField f;
+
/**
- * This class is uninstantiable except natively.
+ * This class is uninstantiable outside the package.
*/
- private Field(Class declaringClass, String name, int slot)
+ Field(VMField f)
{
- this.declaringClass = declaringClass;
- this.name = name;
- this.slot = slot;
+ this.f = f;
+ f.f = this;
}
/**
*/
public Class<?> getDeclaringClass()
{
- return declaringClass;
+ return (Class<?>) f.getDeclaringClass();
}
/**
*/
public String getName()
{
- return name;
+ return f.getName();
}
/**
- * Return the raw modifiers for this field.
- * @return the field's modifiers
- */
- private native int getModifiersInternal();
-
- /**
* Gets the modifiers this field uses. Use the <code>Modifier</code>
* class to interpret the values. A field can only have a subset of the
* following modifiers: public, private, protected, static, final,
*/
public int getModifiers()
{
- return getModifiersInternal() & FIELD_MODIFIERS;
+ return f.getModifiersInternal() & FIELD_MODIFIERS;
}
/**
*/
public boolean isSynthetic()
{
- return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ return (f.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
}
/**
*/
public boolean isEnumConstant()
{
- return (getModifiersInternal() & Modifier.ENUM) != 0;
+ return (f.getModifiersInternal() & Modifier.ENUM) != 0;
}
/**
* Gets the type of this field.
* @return the type of this field
*/
- public native Class<?> getType();
+ public Class<?> getType()
+ {
+ return f.getType();
+ }
/**
* Compare two objects to see if they are semantically equivalent.
*/
public boolean equals(Object o)
{
- if (!(o instanceof Field))
- return false;
- Field that = (Field)o;
- if (this.getDeclaringClass() != that.getDeclaringClass())
- return false;
- if (!this.getName().equals(that.getName()))
- return false;
- if (this.getType() != that.getType())
- return false;
- return true;
+ return f.equals(o);
}
/**
*/
public int hashCode()
{
- return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+ return f.getDeclaringClass().getName().hashCode() ^ f.getName().hashCode();
}
/**
public String toString()
{
// 64 is a reasonable buffer initial size for field
- StringBuilder sb = new StringBuilder(64);
+ CPStringBuilder sb = new CPStringBuilder(64);
Modifier.toString(getModifiers(), sb).append(' ');
sb.append(ClassHelper.getUserName(getType())).append(' ');
sb.append(getDeclaringClass().getName()).append('.');
public String toGenericString()
{
- StringBuilder sb = new StringBuilder(64);
+ CPStringBuilder sb = new CPStringBuilder(64);
Modifier.toString(getModifiers(), sb).append(' ');
sb.append(getGenericType()).append(' ');
sb.append(getDeclaringClass().getName()).append('.');
* @see #getFloat(Object)
* @see #getDouble(Object)
*/
- public native Object get(Object o)
- throws IllegalAccessException;
+ public Object get(Object o)
+ throws IllegalAccessException
+ {
+ return f.get(o);
+ }
/**
* Get the value of this boolean Field. If the field is static,
* class initialization, which then failed
* @see #get(Object)
*/
- public native boolean getBoolean(Object o)
- throws IllegalAccessException;
+ public boolean getBoolean(Object o)
+ throws IllegalAccessException
+ {
+ return f.getBoolean(o);
+ }
/**
* Get the value of this byte Field. If the field is static,
* class initialization, which then failed
* @see #get(Object)
*/
- public native byte getByte(Object o)
- throws IllegalAccessException;
+ public byte getByte(Object o)
+ throws IllegalAccessException
+ {
+ return f.getByte(o);
+ }
/**
* Get the value of this Field as a char. If the field is static,
* class initialization, which then failed
* @see #get(Object)
*/
- public native char getChar(Object o)
- throws IllegalAccessException;
+ public char getChar(Object o)
+ throws IllegalAccessException
+ {
+ return f.getChar(o);
+ }
/**
* Get the value of this Field as a short. If the field is static,
* class initialization, which then failed
* @see #get(Object)
*/
- public native short getShort(Object o)
- throws IllegalAccessException;
+ public short getShort(Object o)
+ throws IllegalAccessException
+ {
+ return f.getShort(o);
+ }
/**
* Get the value of this Field as an int. If the field is static,
* class initialization, which then failed
* @see #get(Object)
*/
- public native int getInt(Object o)
- throws IllegalAccessException;
+ public int getInt(Object o)
+ throws IllegalAccessException
+ {
+ return f.getInt(o);
+ }
/**
* Get the value of this Field as a long. If the field is static,
* class initialization, which then failed
* @see #get(Object)
*/
- public native long getLong(Object o)
- throws IllegalAccessException;
+ public long getLong(Object o)
+ throws IllegalAccessException
+ {
+ return f.getLong(o);
+ }
/**
* Get the value of this Field as a float. If the field is static,
* class initialization, which then failed
* @see #get(Object)
*/
- public native float getFloat(Object o)
- throws IllegalAccessException;
+ public float getFloat(Object o)
+ throws IllegalAccessException
+ {
+ return f.getFloat(o);
+ }
/**
* Get the value of this Field as a double. If the field is static,
* class initialization, which then failed
* @see #get(Object)
*/
- public native double getDouble(Object o)
- throws IllegalAccessException;
+ public double getDouble(Object o)
+ throws IllegalAccessException
+ {
+ return f.getDouble(o);
+ }
/**
* Set the value of this Field. If it is a primitive field, the value
* @see #setFloat(Object, float)
* @see #setDouble(Object, double)
*/
- public native void set(Object o, Object value)
- throws IllegalAccessException;
+ public void set(Object o, Object value)
+ throws IllegalAccessException
+ {
+ f.set(o, value);
+ }
/**
* Set this boolean Field. If the field is static, <code>o</code> will be
* class initialization, which then failed
* @see #set(Object, Object)
*/
- public native void setBoolean(Object o, boolean value)
- throws IllegalAccessException;
+ public void setBoolean(Object o, boolean value)
+ throws IllegalAccessException
+ {
+ f.setBoolean(o, value);
+ }
/**
* Set this byte Field. If the field is static, <code>o</code> will be
* class initialization, which then failed
* @see #set(Object, Object)
*/
- public native void setByte(Object o, byte value)
- throws IllegalAccessException;
+ public void setByte(Object o, byte value)
+ throws IllegalAccessException
+ {
+ f.setByte(o, value);
+ }
/**
* Set this char Field. If the field is static, <code>o</code> will be
* class initialization, which then failed
* @see #set(Object, Object)
*/
- public native void setChar(Object o, char value)
- throws IllegalAccessException;
+ public void setChar(Object o, char value)
+ throws IllegalAccessException
+ {
+ f.setChar(o, value);
+ }
/**
* Set this short Field. If the field is static, <code>o</code> will be
* class initialization, which then failed
* @see #set(Object, Object)
*/
- public native void setShort(Object o, short value)
- throws IllegalAccessException;
+ public void setShort(Object o, short value)
+ throws IllegalAccessException
+ {
+ f.setShort(o, value);
+ }
/**
* Set this int Field. If the field is static, <code>o</code> will be
* class initialization, which then failed
* @see #set(Object, Object)
*/
- public native void setInt(Object o, int value)
- throws IllegalAccessException;
+ public void setInt(Object o, int value)
+ throws IllegalAccessException
+ {
+ f.setInt(o, value);
+ }
/**
* Set this long Field. If the field is static, <code>o</code> will be
* class initialization, which then failed
* @see #set(Object, Object)
*/
- public native void setLong(Object o, long value)
- throws IllegalAccessException;
+ public void setLong(Object o, long value)
+ throws IllegalAccessException
+ {
+ f.setLong(o, value);
+ }
/**
* Set this float Field. If the field is static, <code>o</code> will be
* class initialization, which then failed
* @see #set(Object, Object)
*/
- public native void setFloat(Object o, float value)
- throws IllegalAccessException;
+ public void setFloat(Object o, float value)
+ throws IllegalAccessException
+ {
+ f.setFloat(o, value);
+ }
/**
* Set this double Field. If the field is static, <code>o</code> will be
* class initialization, which then failed
* @see #set(Object, Object)
*/
- public native void setDouble(Object o, double value)
- throws IllegalAccessException;
+ public void setDouble(Object o, double value)
+ throws IllegalAccessException
+ {
+ f.setDouble(o, value);
+ }
/**
* Return the generic type of the field. If the field type is not a generic
*/
public Type getGenericType()
{
- String signature = getSignature();
- if (signature == null)
- return getType();
- FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(),
- signature);
+ if (p == null)
+ {
+ String signature = f.getSignature();
+ if (signature == null)
+ return getType();
+ p = new FieldSignatureParser(getDeclaringClass(),
+ signature);
+ }
return p.getFieldType();
}
/**
- * Return the String in the Signature attribute for this field. If there
- * is no Signature attribute, return null.
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ // Inescapable as the VM layer is 1.4 based. T will erase to Annotation anyway.
+ @SuppressWarnings("unchecked") T ann = (T) f.getAnnotation(annotationClass);
+ return ann;
+ }
+
+ /**
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
*/
- private native String getSignature();
+ public Annotation[] getDeclaredAnnotations()
+ {
+ return f.getDeclaredAnnotations();
+ }
+
}