diff options
| author | Grzegorz B. Prokopski <gadek@debian.org> | 2004-03-28 05:27:14 +0000 |
|---|---|---|
| committer | Grzegorz B. Prokopski <gadek@debian.org> | 2004-03-28 05:27:14 +0000 |
| commit | ee5617175c26cb51da3ae6685f7fc1f1ccf561a2 (patch) | |
| tree | ac02604447d64d6879d9e20343a822149995682c /vm/reference/java/lang/reflect/Field.java | |
| parent | b806d7e52f7cb01ae230af77123c9484113e1f4e (diff) | |
| download | classpath-ee5617175c26cb51da3ae6685f7fc1f1ccf561a2.tar.gz | |
2004-03-28 Grzegorz B. Prokopski <gadek@debian.org>
* Merged vm/reference implementation of these reflection elements,
that can be realized in Java:
vm/reference/java/lang/reflect/Constructor.java,
vm/reference/java/lang/reflect/Field.java,
vm/reference/java/lang/reflect/Makefile.am,
vm/reference/java/lang/reflect/Method.java,
vm/reference/java/lang/reflect/ReflectUtil.java.
Diffstat (limited to 'vm/reference/java/lang/reflect/Field.java')
| -rw-r--r-- | vm/reference/java/lang/reflect/Field.java | 353 |
1 files changed, 330 insertions, 23 deletions
diff --git a/vm/reference/java/lang/reflect/Field.java b/vm/reference/java/lang/reflect/Field.java index 36469796b..2c0821233 100644 --- a/vm/reference/java/lang/reflect/Field.java +++ b/vm/reference/java/lang/reflect/Field.java @@ -62,6 +62,7 @@ package java.lang.reflect; * * @author John Keiser * @author Eric Blake <ebb9@email.byu.edu> + * @author David Belanger <dbelan2@cs.mcgill.ca> * @see Member * @see Class * @see Class#getField(String) @@ -74,10 +75,23 @@ package java.lang.reflect; public final class Field extends AccessibleObject implements Member { - private Class declaringClass; - private String name; private int slot; + private String name; + private Class declaringClass; + private Class type; + + + + + byte[] vmData; + private Field(byte[] vmData) + { + this.vmData = vmData; + } + + + /** * This class is uninstantiable except natively. */ @@ -95,8 +109,14 @@ extends AccessibleObject implements Member */ public Class getDeclaringClass() { + if (declaringClass == null) + { + declaringClass = nativeGetDeclaringClass(vmData); + } return declaringClass; } + public static native Class nativeGetDeclaringClass(byte[] vmData); + /** * Gets the name of this field. @@ -104,8 +124,14 @@ extends AccessibleObject implements Member */ public String getName() { + if (name == null) + { + name = nativeGetName(vmData); + } return name; } + public static native String nativeGetName(byte[] vmData); + /** * Gets the modifiers this field uses. Use the <code>Modifier</code> @@ -116,18 +142,31 @@ extends AccessibleObject implements Member * @return an integer representing the modifiers to this Member * @see Modifier */ - public native int getModifiers(); + public int getModifiers() { + return nativeGetModifiers(vmData); + } + private native int nativeGetModifiers(byte[] vmData); /** * Gets the type of this field. * @return the type of this field */ - public native Class getType(); + public Class getType() + { + if (type == null) + { + type = nativeGetType(vmData); + } + return type; + } + public static native Class nativeGetType(byte[] vmData); + + /** * Compare two objects to see if they are semantically equivalent. * Two Fields are semantically equivalent if they have the same declaring - * class, name, and type. Since you can't creat a Field except through + * class, name, and type. Since you can't create a Field except through * the VM, this is just the == relation. * * @param o the object to compare to @@ -176,6 +215,16 @@ extends AccessibleObject implements Member sb.append(getName()); return sb.toString(); } + + + // DB: + // + // ****** TODO: Add checks to the get.../set... methods. + // + // All checks are done on the Java side for simplicity. + // + + /** * Get the value of this Field. If it is primitive, it will be wrapped @@ -217,9 +266,90 @@ extends AccessibleObject implements Member * @see #getFloat(Object) * @see #getDouble(Object) */ - public native Object get(Object o) + public Object get(Object o) + throws IllegalAccessException + { + + // Checks are delegated to the getTYPE methods + + Class type; + type = getType(); + if (type == Boolean.TYPE) { + return getBoolean(o) ? Boolean.TRUE : Boolean.FALSE; + } else if (type == Byte.TYPE) { + return new Byte(getByte(o)); + } else if (type == Short.TYPE) { + return new Short(getShort(o)); + } else if (type == Character.TYPE) { + return new Character(getChar(o)); + } else if (type == Integer.TYPE) { + return new Integer(getInt(o)); + } else if (type == Long.TYPE) { + return new Long(getLong(o)); + } else if (type == Float.TYPE) { + return new Float(getFloat(o)); + } else if (type == Double.TYPE) { + return new Double(getDouble(o)); + } else { + // for this one, we do the checks here + + checkField(type, o, null); + + return nativeGetReference(vmData, o); + + } + } + private native Object nativeGetReference(byte[] vmData, Object o) throws IllegalAccessException; + // Performs some checks fields access getTYPE() methods. + private void checkField(Object o, Class acceptType) { + checkField(getType(), o, new Class[] { acceptType } ); + } + private void checkField(Object o, Class[] acceptTypes) { + checkField(getType(), o, acceptTypes); + } + + // + // If acceptTypes is null, the any field type is good. + // + private void checkField(Class type, Object o, Class[] acceptTypes) { + if (!Modifier.isStatic(getModifiers())) { + // instance field checks + if (o == null) { + throw new NullPointerException(); + } + + if (!(getDeclaringClass().isInstance(o))) { + throw new IllegalArgumentException(); + } + } + + + // access check + + // *** TODO *** + + + + + // Acceptable field types + // Ex: getBoolean can only be perform on a field of type boolean + if (acceptTypes != null) { + boolean ok = false; // assume not okay + for (int i = 0; i < acceptTypes.length; i++) { + if (type == acceptTypes[i]) { + ok = true; + break; + } + } + if (!ok) { + throw new IllegalArgumentException(); + } + } + } + + /** * Get the value of this boolean Field. If the field is static, * <code>o</code> will be ignored. @@ -237,8 +367,15 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #get(Object) */ - public native boolean getBoolean(Object o) + public boolean getBoolean(Object o) + throws IllegalAccessException + { + checkField(o, Boolean.TYPE); + return nativeGetBoolean(vmData, o); + } + private native boolean nativeGetBoolean(byte[] vmData, Object o) throws IllegalAccessException; + /** * Get the value of this byte Field. If the field is static, @@ -257,9 +394,17 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #get(Object) */ - public native byte getByte(Object o) + public byte getByte(Object o) + throws IllegalAccessException + { + checkField(o, Byte.TYPE); + return nativeGetByte(vmData, o); + } + + private native byte nativeGetByte(byte[] vmData, Object o) throws IllegalAccessException; + /** * Get the value of this Field as a char. If the field is static, * <code>o</code> will be ignored. @@ -275,7 +420,14 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #get(Object) */ - public native char getChar(Object o) + public char getChar(Object o) + throws IllegalAccessException + { + checkField(o, Character.TYPE); + return nativeGetChar(vmData, o); + } + + private native char nativeGetChar(byte[] vmData, Object o) throws IllegalAccessException; /** @@ -295,7 +447,12 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #get(Object) */ - public native short getShort(Object o) + public short getShort(Object o) + throws IllegalAccessException { + checkField(o, new Class[] { Byte.TYPE, Short.TYPE }); + return nativeGetShort(vmData, o); + } + private native short nativeGetShort(byte[] vmData, Object o) throws IllegalAccessException; /** @@ -315,7 +472,14 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #get(Object) */ - public native int getInt(Object o) + public int getInt(Object o) + throws IllegalAccessException + { + checkField(o, new Class[] { Byte.TYPE, Short.TYPE, + Character.TYPE, Integer.TYPE } ); + return nativeGetInt(vmData, o); + } + private native int nativeGetInt(byte[] vmData, Object o) throws IllegalAccessException; /** @@ -335,7 +499,15 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #get(Object) */ - public native long getLong(Object o) + public long getLong(Object o) + throws IllegalAccessException + { + checkField(o, new Class[] { Byte.TYPE, Short.TYPE, Character.TYPE, + Integer.TYPE, Long.TYPE }); + return nativeGetLong(vmData, o); + } + + private native long nativeGetLong(byte[] vmData, Object o) throws IllegalAccessException; /** @@ -355,7 +527,14 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #get(Object) */ - public native float getFloat(Object o) + public float getFloat(Object o) + throws IllegalAccessException + { + checkField(o, new Class[] { Byte.TYPE, Short.TYPE, Character.TYPE, + Integer.TYPE, Long.TYPE, Float.TYPE }); + return nativeGetFloat(vmData, o); + } + public native float nativeGetFloat(byte[] vmData, Object o) throws IllegalAccessException; /** @@ -376,7 +555,15 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #get(Object) */ - public native double getDouble(Object o) + public double getDouble(Object o) + throws IllegalAccessException + { + checkField(o, new Class[] { Byte.TYPE, Short.TYPE, Character.TYPE, + Integer.TYPE, Long.TYPE, Float.TYPE, + Double.TYPE }); + return nativeGetDouble(vmData, o); + } + private native double nativeGetDouble(byte[] vmData, Object o) throws IllegalAccessException; /** @@ -424,9 +611,63 @@ extends AccessibleObject implements Member * @see #setFloat(Object, float) * @see #setDouble(Object, double) */ - public native void set(Object o, Object value) + public void set(Object o, Object value) + throws IllegalAccessException + { + + // Checks are delegated to the setTYPE methods + + Class type; + + type = getType(); + + if (type.isPrimitive()) { + // this is a primitive field, unwrap + + if (value instanceof Boolean) { + setBoolean(o, ((Boolean) value).booleanValue()); + } else if (value instanceof Byte) { + setByte(o, ((Byte) value).byteValue()); + } else if (value instanceof Short) { + setShort(o, ((Short) value).shortValue()); + } else if (value instanceof Character) { + setChar(o, ((Character) value).charValue()); + } else if (value instanceof Integer) { + setInt(o, ((Integer) value).intValue()); + } else if (value instanceof Long) { + setLong(o, ((Long) value).longValue()); + } else if (value instanceof Float) { + setFloat(o, ((Float) value).floatValue()); + } else if (value instanceof Double) { + setDouble(o, ((Double) value).doubleValue()); + } else { + // unable to unwrap + throw new IllegalArgumentException(); + } + + } else { + // reference type + + checkField(type, o, null); + + // cannot store reference A into field of type B if A is + // not instance of B + if (!type.isInstance(value)) { + throw new IllegalArgumentException(); + } + + nativeSetReference(vmData, o, value); + + } + + } + + private native void nativeSetReference(byte[] vmData, + Object o, + Object value) throws IllegalAccessException; + /** * Set this boolean Field. If the field is static, <code>o</code> will be * ignored. @@ -444,9 +685,17 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #set(Object, Object) */ - public native void setBoolean(Object o, boolean value) + public void setBoolean(Object o, boolean value) + throws IllegalAccessException + { + checkField(o, Boolean.TYPE); + nativeSetBoolean(vmData, o, value); + } + + private native void nativeSetBoolean(byte[] vmData, Object o, boolean value) throws IllegalAccessException; + /** * Set this byte Field. If the field is static, <code>o</code> will be * ignored. @@ -464,7 +713,15 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #set(Object, Object) */ - public native void setByte(Object o, byte value) + public void setByte(Object o, byte value) + throws IllegalAccessException + { + checkField(o, new Class[] { Byte.TYPE, Short.TYPE, Integer.TYPE, + Long.TYPE, Float.TYPE, Double.TYPE }); + nativeSetByte(vmData, o, value); + } + + private native void nativeSetByte(byte[] vmData, Object o, byte value) throws IllegalAccessException; /** @@ -484,9 +741,18 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #set(Object, Object) */ - public native void setChar(Object o, char value) + public void setChar(Object o, char value) + throws IllegalAccessException + { + checkField(o, new Class[] { Character.TYPE, Integer.TYPE, Long.TYPE, + Float.TYPE, Double.TYPE } ); + nativeSetChar(vmData, o, value); + } + + private native void nativeSetChar(byte[] vmData, Object o, char value) throws IllegalAccessException; + /** * Set this short Field. If the field is static, <code>o</code> will be * ignored. @@ -504,7 +770,15 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #set(Object, Object) */ - public native void setShort(Object o, short value) + public void setShort(Object o, short value) + throws IllegalAccessException + { + checkField(o, new Class[] { Short.TYPE, Integer.TYPE, Long.TYPE, + Float.TYPE, Double.TYPE }); + nativeSetShort(vmData, o, value); + } + + private native void nativeSetShort(byte[] vmData, Object o, short value) throws IllegalAccessException; /** @@ -524,9 +798,18 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #set(Object, Object) */ - public native void setInt(Object o, int value) + public void setInt(Object o, int value) + throws IllegalAccessException + { + checkField(o, new Class[] { Integer.TYPE, Long.TYPE, Float.TYPE, + Double.TYPE }); + nativeSetInt(vmData, o, value); + } + + private native void nativeSetInt(byte[] vmData, Object o, int value) throws IllegalAccessException; + /** * Set this long Field. If the field is static, <code>o</code> will be * ignored. @@ -544,9 +827,16 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #set(Object, Object) */ - public native void setLong(Object o, long value) + public void setLong(Object o, long value) + throws IllegalAccessException { + checkField(o, new Class[] { Long.TYPE, Float.TYPE, Double.TYPE }); + nativeSetLong(vmData, o, value); + } + + private native void nativeSetLong(byte[] vmData, Object o, long value) throws IllegalAccessException; + /** * Set this float Field. If the field is static, <code>o</code> will be * ignored. @@ -564,8 +854,17 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #set(Object, Object) */ - public native void setFloat(Object o, float value) + public void setFloat(Object o, float value) + throws IllegalAccessException + { + // DB: why float or long, why not double also? + checkField(o, new Class[] { Float.TYPE, Long.TYPE }); + nativeSetFloat(vmData, o, value); + } + + private native void nativeSetFloat(byte[] vmData, Object o, float value) throws IllegalAccessException; + /** * Set this double Field. If the field is static, <code>o</code> will be @@ -584,6 +883,14 @@ extends AccessibleObject implements Member * class initialization, which then failed * @see #set(Object, Object) */ - public native void setDouble(Object o, double value) + public void setDouble(Object o, double value) + throws IllegalAccessException + { + checkField(o, Double.TYPE); + nativeSetDouble(vmData, o, value); + } + + private native void nativeSetDouble(byte[] vmData, Object o, double value) throws IllegalAccessException; + } |
