1 /* java.lang.reflect.Field - reflection of Java fields
2    Copyright (C) 1998, 2001 Free Software Foundation, Inc.
3 
4 Modifications Copyright (C) 2004 by Etienne Gagnon.
5 Modifications Copyright (C) 2004 by David Belanger.
6 Modifications Copyright (C) 2004 by Grzegorz Prokopski.
7 
8 This file is part of GNU Classpath.
9 
10 GNU Classpath is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14 
15 GNU Classpath is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with GNU Classpath; see the file COPYING.  If not, write to the
22 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 02110-1301 USA.
24 
25 Linking this library statically or dynamically with other modules is
26 making a combined work based on this library.  Thus, the terms and
27 conditions of the GNU General Public License cover the whole
28 combination.
29 
30 As a special exception, the copyright holders of this library give you
31 permission to link this library with independent modules to produce an
32 executable, regardless of the license terms of these independent
33 modules, and to copy and distribute the resulting executable under
34 terms of your choice, provided that you also meet, for each linked
35 independent module, the terms and conditions of the license of that
36 module.  An independent module is a module which is not derived from
37 or based on this library.  If you modify this library, you may extend
38 this exception to your version of the library, but you are not
39 obligated to do so.  If you do not wish to do so, delete this
40 exception statement from your version. */
41 
42 
43 package java.lang.reflect;
44 
45 /**
46  * The Field class represents a member variable of a class. It also allows
47  * dynamic access to a member, via reflection. This works for both
48  * static and instance fields. Operations on Field objects know how to
49  * do widening conversions, but throw {@link IllegalArgumentException} if
50  * a narrowing conversion would be necessary. You can query for information
51  * on this Field regardless of location, but get and set access may be limited
52  * by Java language access controls. If you can't do it in the compiler, you
53  * can't normally do it here either.<p>
54  *
55  * <B>Note:</B> This class returns and accepts types as Classes, even
56  * primitive types; there are Class types defined that represent each
57  * different primitive type.  They are <code>java.lang.Boolean.TYPE,
58  * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
59  * byte.class</code>, etc.  These are not to be confused with the
60  * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
61  * real classes.<p>
62  *
63  * Also note that this is not a serializable class.  It is entirely feasible
64  * to make it serializable using the Externalizable interface, but this is
65  * on Sun, not me.
66  *
67  * @author John Keiser
68  * @author Eric Blake <ebb9@email.byu.edu>
69  * @author David Belanger <dbelan2@cs.mcgill.ca>
70  * @see Member
71  * @see Class
72  * @see Class#getField(String)
73  * @see Class#getDeclaredField(String)
74  * @see Class#getFields()
75  * @see Class#getDeclaredFields()
76  * @since 1.1
77  * @status updated to 1.4
78  */
79 public final class Field
80 extends AccessibleObject implements Member
81 {
82   //private Class declaringClass;
83   //private String name;
84   private int slot;
85 
86   private String name;
87   private Class declaringClass;
88   private Class type;
89 
90 
91 
92 
93   byte[] vmData;
Field(byte[] vmData)94   private  Field(byte[] vmData)
95   {
96     this.vmData = vmData;
97   }
98 
99 
100 
101   /**
102    * This class is uninstantiable except natively.
103    */
Field(Class declaringClass, String name, int slot)104   private Field(Class declaringClass, String name, int slot)
105   {
106     this.declaringClass = declaringClass;
107     this.name = name;
108     this.slot = slot;
109   }
110 
111   /**
112    * Gets the class that declared this field, or the class where this field
113    * is a non-inherited member.
114    * @return the class that declared this member
115    */
116   /*
117   public Class getDeclaringClass()
118   {
119     return declaringClass;
120   }
121   */
getDeclaringClass()122   public Class getDeclaringClass()
123   {
124     if (declaringClass == null)
125     {
126       declaringClass = nativeGetDeclaringClass(vmData);
127     }
128     return declaringClass;
129   }
nativeGetDeclaringClass(byte[] vmData)130   public static native Class nativeGetDeclaringClass(byte[] vmData);
131 
132 
133 
134   /**
135    * Gets the name of this field.
136    * @return the name of this field
137    */
138   /*
139   public String getName()
140   {
141     return name;
142   }
143   */
getName()144   public String getName()
145   {
146     if (name == null)
147     {
148       name = nativeGetName(vmData);
149     }
150     return name;
151   }
nativeGetName(byte[] vmData)152   public static native String nativeGetName(byte[] vmData);
153 
154 
155   /**
156    * Gets the modifiers this field uses.  Use the <code>Modifier</code>
157    * class to interpret the values.  A field can only have a subset of the
158    * following modifiers: public, private, protected, static, final,
159    * transient, and volatile.
160    *
161    * @return an integer representing the modifiers to this Member
162    * @see Modifier
163    */
getModifiers()164   public int getModifiers() {
165     return nativeGetModifiers(vmData);
166   }
nativeGetModifiers(byte[] vmData)167   private native int nativeGetModifiers(byte[] vmData);
168 
169   /**
170    * Gets the type of this field.
171    * @return the type of this field
172    */
173   //public native Class getType();
174 
getType()175   public Class getType()
176   {
177     if (type == null)
178     {
179       type = nativeGetType(vmData);
180     }
181     return type;
182   }
nativeGetType(byte[] vmData)183   public static native Class nativeGetType(byte[] vmData);
184 
185 
186 
187   /**
188    * Compare two objects to see if they are semantically equivalent.
189    * Two Fields are semantically equivalent if they have the same declaring
190    * class, name, and type. Since you can't create a Field except through
191    * the VM, this is just the == relation.
192    *
193    * @param o the object to compare to
194    * @return <code>true</code> if they are equal; <code>false</code> if not
195    */
equals(Object o)196   public boolean equals(Object o)
197   {
198     if (!(o instanceof Field))
199       return false;
200     Field that = (Field)o;
201     if (this.getDeclaringClass() != that.getDeclaringClass())
202       return false;
203     if (!this.getName().equals(that.getName()))
204       return false;
205     if (this.getType() != that.getType())
206       return false;
207     return true;
208   }
209 
210   /**
211    * Get the hash code for the Field. The Field hash code is the hash code
212    * of its name XOR'd with the hash code of its class name.
213    *
214    * @return the hash code for the object.
215    */
hashCode()216   public int hashCode()
217   {
218     return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
219   }
220 
221   /**
222    * Get a String representation of the Field. A Field's String
223    * representation is "&lt;modifiers&gt; &lt;type&gt;
224    * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
225    * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
226    *
227    * @return the String representation of the Field
228    */
toString()229   public String toString()
230   {
231     // 64 is a reasonable buffer initial size for field
232     StringBuffer sb = new StringBuffer(64);
233     Modifier.toString(getModifiers(), sb).append(' ');
234     sb.append(getType().getName()).append(' ');
235     sb.append(getDeclaringClass().getName()).append('.');
236     sb.append(getName());
237     return sb.toString();
238   }
239 
240 
241   // DB:
242   //
243   // ****** TODO: Add checks to the get.../set... methods.
244   //
245   // All checks are done on the Java side for simplicity.
246   //
247 
248 
249 
250   /**
251    * Get the value of this Field.  If it is primitive, it will be wrapped
252    * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
253    *
254    * If the field is static, <code>o</code> will be ignored. Otherwise, if
255    * <code>o</code> is null, you get a <code>NullPointerException</code>,
256    * and if it is incompatible with the declaring class of the field, you
257    * get an <code>IllegalArgumentException</code>.<p>
258    *
259    * Next, if this Field enforces access control, your runtime context is
260    * evaluated, and you may have an <code>IllegalAccessException</code> if
261    * you could not access this field in similar compiled code. If the field
262    * is static, and its class is uninitialized, you trigger class
263    * initialization, which may end in a
264    * <code>ExceptionInInitializerError</code>.<p>
265    *
266    * Finally, the field is accessed, and primitives are wrapped (but not
267    * necessarily in new objects). This method accesses the field of the
268    * declaring class, even if the instance passed in belongs to a subclass
269    * which declares another field to hide this one.
270    *
271    * @param o the object to get the value of this Field from
272    * @return the value of the Field
273    * @throws IllegalAccessException if you could not normally access this field
274    *         (i.e. it is not public)
275    * @throws IllegalArgumentException if <code>o</code> is not an instance of
276    *         the class or interface declaring this field
277    * @throws NullPointerException if <code>o</code> is null and this field
278    *         requires an instance
279    * @throws ExceptionInInitializerError if accessing a static field triggered
280    *         class initialization, which then failed
281    * @see #getBoolean(Object)
282    * @see #getByte(Object)
283    * @see #getChar(Object)
284    * @see #getShort(Object)
285    * @see #getInt(Object)
286    * @see #getLong(Object)
287    * @see #getFloat(Object)
288    * @see #getDouble(Object)
289    */
get(Object o)290   public Object get(Object o)
291     throws IllegalAccessException
292   {
293 
294     // Checks are delegated to the getTYPE methods
295 
296     Class type;
297     type = getType();
298     if (type == Boolean.TYPE) {
299       return getBoolean(o) ? Boolean.TRUE : Boolean.FALSE;
300     } else if (type == Byte.TYPE) {
301       return new Byte(getByte(o));
302     } else if (type == Short.TYPE) {
303       return new Short(getShort(o));
304     } else if (type == Character.TYPE) {
305       return new Character(getChar(o));
306     } else if (type == Integer.TYPE) {
307       return new Integer(getInt(o));
308     } else if (type == Long.TYPE) {
309       return new Long(getLong(o));
310     } else if (type == Float.TYPE) {
311       return new Float(getFloat(o));
312     } else if (type == Double.TYPE) {
313       return new Double(getDouble(o));
314     } else {
315       // for this one, we do the checks here
316 
317       checkField(type, o, null);
318 
319       return nativeGetReference(vmData, o);
320 
321     }
322   }
nativeGetReference(byte[] vmData, Object o)323   private native Object nativeGetReference(byte[] vmData, Object o)
324     throws IllegalAccessException;
325 
326   // Performs some checks fields access getTYPE() methods.
checkField(Object o, Class acceptType)327   private void checkField(Object o, Class acceptType) {
328     checkField(getType(), o, new Class[] { acceptType } );
329   }
checkField(Object o, Class[] acceptTypes)330   private void checkField(Object o, Class[] acceptTypes) {
331     checkField(getType(), o, acceptTypes);
332   }
333 
334   //
335   // If acceptTypes is null, the any field type is good.
336   //
checkField(Class type, Object o, Class[] acceptTypes)337   private void checkField(Class type, Object o, Class[] acceptTypes) {
338     if (!Modifier.isStatic(getModifiers())) {
339       // instance field checks
340       if (o == null) {
341 	throw new NullPointerException();
342       }
343 
344       if (!(getDeclaringClass().isInstance(o))) {
345 	throw new IllegalArgumentException();
346       }
347     }
348 
349 
350     // access check
351 
352     // *** TODO ***
353 
354 
355 
356 
357     // Acceptable field types
358     // Ex: getBoolean can only be perform on a field of type boolean
359     if (acceptTypes != null) {
360       boolean ok = false;  // assume not okay
361       for (int i = 0; i < acceptTypes.length; i++) {
362 	if (type == acceptTypes[i]) {
363 	  ok = true;
364 	  break;
365 	}
366       }
367       if (!ok) {
368 	throw new IllegalArgumentException();
369       }
370     }
371   }
372 
373 
374   /**
375    * Get the value of this boolean Field. If the field is static,
376    * <code>o</code> will be ignored.
377    *
378    * @param o the object to get the value of this Field from
379    * @return the value of the Field
380    * @throws IllegalAccessException if you could not normally access this field
381    *         (i.e. it is not public)
382    * @throws IllegalArgumentException if this is not a boolean field of
383    *         <code>o</code>, or if <code>o</code> is not an instance of the
384    *         declaring class of this field
385    * @throws NullPointerException if <code>o</code> is null and this field
386    *         requires an instance
387    * @throws ExceptionInInitializerError if accessing a static field triggered
388    *         class initialization, which then failed
389    * @see #get(Object)
390    */
getBoolean(Object o)391   public boolean getBoolean(Object o)
392     throws IllegalAccessException
393   {
394     checkField(o, Boolean.TYPE);
395     return nativeGetBoolean(vmData, o);
396   }
nativeGetBoolean(byte[] vmData, Object o)397   private native boolean nativeGetBoolean(byte[] vmData, Object o)
398     throws IllegalAccessException;
399 
400 
401   /**
402    * Get the value of this byte Field. If the field is static,
403    * <code>o</code> will be ignored.
404    *
405    * @param o the object to get the value of this Field from
406    * @return the value of the Field
407    * @throws IllegalAccessException if you could not normally access this field
408    *         (i.e. it is not public)
409    * @throws IllegalArgumentException if this is not a byte field of
410    *         <code>o</code>, or if <code>o</code> is not an instance of the
411    *         declaring class of this field
412    * @throws NullPointerException if <code>o</code> is null and this field
413    *         requires an instance
414    * @throws ExceptionInInitializerError if accessing a static field triggered
415    *         class initialization, which then failed
416    * @see #get(Object)
417    */
getByte(Object o)418   public byte getByte(Object o)
419     throws IllegalAccessException
420   {
421     checkField(o, Byte.TYPE);
422     return nativeGetByte(vmData, o);
423   }
424 
nativeGetByte(byte[] vmData, Object o)425   private native byte nativeGetByte(byte[] vmData, Object o)
426     throws IllegalAccessException;
427 
428 
429   /**
430    * Get the value of this Field as a char. If the field is static,
431    * <code>o</code> will be ignored.
432    *
433    * @throws IllegalAccessException if you could not normally access this field
434    *         (i.e. it is not public)
435    * @throws IllegalArgumentException if this is not a char field of
436    *         <code>o</code>, or if <code>o</code> is not an instance
437    *         of the declaring class of this field
438    * @throws NullPointerException if <code>o</code> is null and this field
439    *         requires an instance
440    * @throws ExceptionInInitializerError if accessing a static field triggered
441    *         class initialization, which then failed
442    * @see #get(Object)
443    */
getChar(Object o)444   public char getChar(Object o)
445     throws IllegalAccessException
446   {
447     checkField(o, Character.TYPE);
448     return nativeGetChar(vmData, o);
449   }
450 
nativeGetChar(byte[] vmData, Object o)451   private native char nativeGetChar(byte[] vmData, Object o)
452     throws IllegalAccessException;
453 
454   /**
455    * Get the value of this Field as a short. If the field is static,
456    * <code>o</code> will be ignored.
457    *
458    * @param o the object to get the value of this Field from
459    * @return the value of the Field
460    * @throws IllegalAccessException if you could not normally access this field
461    *         (i.e. it is not public)
462    * @throws IllegalArgumentException if this is not a byte or short
463    *         field of <code>o</code>, or if <code>o</code> is not an instance
464    *         of the declaring class of this field
465    * @throws NullPointerException if <code>o</code> is null and this field
466    *         requires an instance
467    * @throws ExceptionInInitializerError if accessing a static field triggered
468    *         class initialization, which then failed
469    * @see #get(Object)
470    */
getShort(Object o)471   public short getShort(Object o)
472     throws IllegalAccessException {
473     checkField(o, new Class[] { Byte.TYPE, Short.TYPE });
474     return nativeGetShort(vmData, o);
475   }
nativeGetShort(byte[] vmData, Object o)476   private native short nativeGetShort(byte[] vmData, Object o)
477     throws IllegalAccessException;
478 
479   /**
480    * Get the value of this Field as an int. If the field is static,
481    * <code>o</code> will be ignored.
482    *
483    * @param o the object to get the value of this Field from
484    * @return the value of the Field
485    * @throws IllegalAccessException if you could not normally access this field
486    *         (i.e. it is not public)
487    * @throws IllegalArgumentException if this is not a byte, short, char, or
488    *         int field of <code>o</code>, or if <code>o</code> is not an
489    *         instance of the declaring class of this field
490    * @throws NullPointerException if <code>o</code> is null and this field
491    *         requires an instance
492    * @throws ExceptionInInitializerError if accessing a static field triggered
493    *         class initialization, which then failed
494    * @see #get(Object)
495    */
getInt(Object o)496   public int getInt(Object o)
497     throws IllegalAccessException
498   {
499     checkField(o, new Class[] { Byte.TYPE, Short.TYPE,
500 			      Character.TYPE, Integer.TYPE } );
501     return nativeGetInt(vmData, o);
502   }
nativeGetInt(byte[] vmData, Object o)503   private native int nativeGetInt(byte[] vmData, Object o)
504     throws IllegalAccessException;
505 
506   /**
507    * Get the value of this Field as a long. If the field is static,
508    * <code>o</code> will be ignored.
509    *
510    * @param o the object to get the value of this Field from
511    * @return the value of the Field
512    * @throws IllegalAccessException if you could not normally access this field
513    *         (i.e. it is not public)
514    * @throws IllegalArgumentException if this is not a byte, short, char, int,
515    *         or long field of <code>o</code>, or if <code>o</code> is not an
516    *         instance of the declaring class of this field
517    * @throws NullPointerException if <code>o</code> is null and this field
518    *         requires an instance
519    * @throws ExceptionInInitializerError if accessing a static field triggered
520    *         class initialization, which then failed
521    * @see #get(Object)
522    */
getLong(Object o)523   public long getLong(Object o)
524     throws IllegalAccessException
525   {
526     checkField(o, new Class[] { Byte.TYPE, Short.TYPE, Character.TYPE,
527 			      Integer.TYPE, Long.TYPE });
528     return nativeGetLong(vmData, o);
529   }
530 
nativeGetLong(byte[] vmData, Object o)531   private native long nativeGetLong(byte[] vmData, Object o)
532     throws IllegalAccessException;
533 
534   /**
535    * Get the value of this Field as a float. If the field is static,
536    * <code>o</code> will be ignored.
537    *
538    * @param o the object to get the value of this Field from
539    * @return the value of the Field
540    * @throws IllegalAccessException if you could not normally access this field
541    *         (i.e. it is not public)
542    * @throws IllegalArgumentException if this is not a byte, short, char, int,
543    *         long, or float field of <code>o</code>, or if <code>o</code> is
544    *         not an instance of the declaring class of this field
545    * @throws NullPointerException if <code>o</code> is null and this field
546    *         requires an instance
547    * @throws ExceptionInInitializerError if accessing a static field triggered
548    *         class initialization, which then failed
549    * @see #get(Object)
550    */
getFloat(Object o)551   public float getFloat(Object o)
552     throws IllegalAccessException
553   {
554     checkField(o, new Class[] { Byte.TYPE, Short.TYPE, Character.TYPE,
555 			      Integer.TYPE, Long.TYPE, Float.TYPE });
556     return nativeGetFloat(vmData, o);
557   }
nativeGetFloat(byte[] vmData, Object o)558   public native float nativeGetFloat(byte[] vmData, Object o)
559     throws IllegalAccessException;
560 
561   /**
562    * Get the value of this Field as a double. If the field is static,
563    * <code>o</code> will be ignored.
564    *
565    * @param o the object to get the value of this Field from
566    * @return the value of the Field
567    * @throws IllegalAccessException if you could not normally access this field
568    *         (i.e. it is not public)
569    * @throws IllegalArgumentException if this is not a byte, short, char, int,
570    *         long, float, or double field of <code>o</code>, or if
571    *         <code>o</code> is not an instance of the declaring class of this
572    *         field
573    * @throws NullPointerException if <code>o</code> is null and this field
574    *         requires an instance
575    * @throws ExceptionInInitializerError if accessing a static field triggered
576    *         class initialization, which then failed
577    * @see #get(Object)
578    */
getDouble(Object o)579   public double getDouble(Object o)
580     throws IllegalAccessException
581   {
582     checkField(o, new Class[] { Byte.TYPE, Short.TYPE, Character.TYPE,
583 				Integer.TYPE, Long.TYPE, Float.TYPE,
584 				Double.TYPE });
585     return nativeGetDouble(vmData, o);
586   }
nativeGetDouble(byte[] vmData, Object o)587   private native double nativeGetDouble(byte[] vmData, Object o)
588     throws IllegalAccessException;
589 
590   /**
591    * Set the value of this Field.  If it is a primitive field, the value
592    * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
593    *
594    * If the field is static, <code>o</code> will be ignored. Otherwise, if
595    * <code>o</code> is null, you get a <code>NullPointerException</code>,
596    * and if it is incompatible with the declaring class of the field, you
597    * get an <code>IllegalArgumentException</code>.<p>
598    *
599    * Next, if this Field enforces access control, your runtime context is
600    * evaluated, and you may have an <code>IllegalAccessException</code> if
601    * you could not access this field in similar compiled code. This also
602    * occurs whether or not there is access control if the field is final.
603    * If the field is primitive, and unwrapping your argument fails, you will
604    * get an <code>IllegalArgumentException</code>; likewise, this error
605    * happens if <code>value</code> cannot be cast to the correct object type.
606    * If the field is static, and its class is uninitialized, you trigger class
607    * initialization, which may end in a
608    * <code>ExceptionInInitializerError</code>.<p>
609    *
610    * Finally, the field is set with the widened value. This method accesses
611    * the field of the declaring class, even if the instance passed in belongs
612    * to a subclass which declares another field to hide this one.
613    *
614    * @param o the object to set this Field on
615    * @param value the value to set this Field to
616    * @throws IllegalAccessException if you could not normally access this field
617    *         (i.e. it is not public)
618    * @throws IllegalArgumentException if <code>value</code> cannot be
619    *         converted by a widening conversion to the underlying type of
620    *         the Field, or if <code>o</code> is not an instance of the class
621    *         declaring this field
622    * @throws NullPointerException if <code>o</code> is null and this field
623    *         requires an instance
624    * @throws ExceptionInInitializerError if accessing a static field triggered
625    *         class initialization, which then failed
626    * @see #setBoolean(Object, boolean)
627    * @see #setByte(Object, byte)
628    * @see #setChar(Object, char)
629    * @see #setShort(Object, short)
630    * @see #setInt(Object, int)
631    * @see #setLong(Object, long)
632    * @see #setFloat(Object, float)
633    * @see #setDouble(Object, double)
634    */
set(Object o, Object value)635   public void set(Object o, Object value)
636     throws IllegalAccessException
637   {
638 
639     // Checks are delegated to the setTYPE methods
640 
641     Class type;
642 
643     type = getType();
644 
645     if (type.isPrimitive()) {
646       // this is a primitive field, unwrap
647 
648       if (value instanceof Boolean) {
649 	setBoolean(o, ((Boolean) value).booleanValue());
650       } else if (value instanceof Byte) {
651 	setByte(o, ((Byte) value).byteValue());
652       } else if (value instanceof Short) {
653 	setShort(o, ((Short) value).shortValue());
654       } else if (value instanceof Character) {
655 	setChar(o, ((Character) value).charValue());
656       } else if (value instanceof Integer) {
657 	setInt(o, ((Integer) value).intValue());
658       } else if (value instanceof Long) {
659 	setLong(o, ((Long) value).longValue());
660       } else if (value instanceof Float) {
661 	setFloat(o, ((Float) value).floatValue());
662       } else if (value instanceof Double) {
663 	setDouble(o, ((Double) value).doubleValue());
664       } else {
665 	// unable to unwrap
666 	throw new IllegalArgumentException();
667       }
668 
669     } else {
670       // reference type
671 
672       checkField(type, o, null);
673 
674       // cannot store reference A into field of type B if A is
675       // not instance of B
676       if (!type.isInstance(value)) {
677 	throw new IllegalArgumentException();
678       }
679 
680       nativeSetReference(vmData, o, value);
681 
682     }
683 
684   }
685 
nativeSetReference(byte[] vmData, Object o, Object value)686   private native void nativeSetReference(byte[] vmData,
687 					 Object o,
688 					 Object value)
689     throws IllegalAccessException;
690 
691 
692   /**
693    * Set this boolean Field. If the field is static, <code>o</code> will be
694    * ignored.
695    *
696    * @param o the object to set this Field on
697    * @param value the value to set this Field to
698    * @throws IllegalAccessException if you could not normally access this field
699    *         (i.e. it is not public)
700    * @throws IllegalArgumentException if this is not a boolean field, or if
701    *         <code>o</code> is not an instance of the class declaring this
702    *         field
703    * @throws NullPointerException if <code>o</code> is null and this field
704    *         requires an instance
705    * @throws ExceptionInInitializerError if accessing a static field triggered
706    *         class initialization, which then failed
707    * @see #set(Object, Object)
708    */
setBoolean(Object o, boolean value)709   public void setBoolean(Object o, boolean value)
710     throws IllegalAccessException
711   {
712     checkField(o, Boolean.TYPE);
713     nativeSetBoolean(vmData, o, value);
714   }
715 
nativeSetBoolean(byte[] vmData, Object o, boolean value)716   private native void nativeSetBoolean(byte[] vmData, Object o, boolean value)
717     throws IllegalAccessException;
718 
719 
720   /**
721    * Set this byte Field. If the field is static, <code>o</code> will be
722    * ignored.
723    *
724    * @param o the object to set this Field on
725    * @param value the value to set this Field to
726    * @throws IllegalAccessException if you could not normally access this field
727    *         (i.e. it is not public)
728    * @throws IllegalArgumentException if this is not a byte, short, int, long,
729    *         float, or double field, or if <code>o</code> is not an instance
730    *         of the class declaring this field
731    * @throws NullPointerException if <code>o</code> is null and this field
732    *         requires an instance
733    * @throws ExceptionInInitializerError if accessing a static field triggered
734    *         class initialization, which then failed
735    * @see #set(Object, Object)
736    */
setByte(Object o, byte value)737   public void setByte(Object o, byte value)
738     throws IllegalAccessException
739   {
740     checkField(o, new Class[] { Byte.TYPE, Short.TYPE, Integer.TYPE,
741 				Long.TYPE, Float.TYPE, Double.TYPE });
742     nativeSetByte(vmData, o, value);
743   }
744 
nativeSetByte(byte[] vmData, Object o, byte value)745   private native void nativeSetByte(byte[] vmData, Object o, byte value)
746     throws IllegalAccessException;
747 
748   /**
749    * Set this char Field. If the field is static, <code>o</code> will be
750    * ignored.
751    *
752    * @param o the object to set this Field on
753    * @param value the value to set this Field to
754    * @throws IllegalAccessException if you could not normally access this field
755    *         (i.e. it is not public)
756    * @throws IllegalArgumentException if this is not a char, int, long,
757    *         float, or double field, or if <code>o</code> is not an instance
758    *         of the class declaring this field
759    * @throws NullPointerException if <code>o</code> is null and this field
760    *         requires an instance
761    * @throws ExceptionInInitializerError if accessing a static field triggered
762    *         class initialization, which then failed
763    * @see #set(Object, Object)
764    */
setChar(Object o, char value)765   public void setChar(Object o, char value)
766     throws IllegalAccessException
767   {
768     checkField(o, new Class[] { Character.TYPE, Integer.TYPE, Long.TYPE,
769 				Float.TYPE, Double.TYPE } );
770     nativeSetChar(vmData, o, value);
771   }
772 
nativeSetChar(byte[] vmData, Object o, char value)773   private native void nativeSetChar(byte[] vmData, Object o, char value)
774     throws IllegalAccessException;
775 
776 
777   /**
778    * Set this short Field. If the field is static, <code>o</code> will be
779    * ignored.
780    *
781    * @param o the object to set this Field on
782    * @param value the value to set this Field to
783    * @throws IllegalAccessException if you could not normally access this field
784    *         (i.e. it is not public)
785    * @throws IllegalArgumentException if this is not a short, int, long,
786    *         float, or double field, or if <code>o</code> is not an instance
787    *         of the class declaring this field
788    * @throws NullPointerException if <code>o</code> is null and this field
789    *         requires an instance
790    * @throws ExceptionInInitializerError if accessing a static field triggered
791    *         class initialization, which then failed
792    * @see #set(Object, Object)
793    */
setShort(Object o, short value)794   public void setShort(Object o, short value)
795     throws IllegalAccessException
796   {
797     checkField(o, new Class[] { Short.TYPE, Integer.TYPE, Long.TYPE,
798 				Float.TYPE, Double.TYPE });
799     nativeSetShort(vmData, o, value);
800   }
801 
nativeSetShort(byte[] vmData, Object o, short value)802   private native void nativeSetShort(byte[] vmData, Object o, short value)
803     throws IllegalAccessException;
804 
805   /**
806    * Set this int Field. If the field is static, <code>o</code> will be
807    * ignored.
808    *
809    * @param o the object to set this Field on
810    * @param value the value to set this Field to
811    * @throws IllegalAccessException if you could not normally access this field
812    *         (i.e. it is not public)
813    * @throws IllegalArgumentException if this is not an int, long, float, or
814    *         double field, or if <code>o</code> is not an instance of the
815    *         class declaring this field
816    * @throws NullPointerException if <code>o</code> is null and this field
817    *         requires an instance
818    * @throws ExceptionInInitializerError if accessing a static field triggered
819    *         class initialization, which then failed
820    * @see #set(Object, Object)
821    */
setInt(Object o, int value)822   public void setInt(Object o, int value)
823     throws IllegalAccessException
824   {
825     checkField(o, new Class[] { Integer.TYPE, Long.TYPE, Float.TYPE,
826 				Double.TYPE });
827     nativeSetInt(vmData, o, value);
828   }
829 
nativeSetInt(byte[] vmData, Object o, int value)830   private native void nativeSetInt(byte[] vmData, Object o, int value)
831     throws IllegalAccessException;
832 
833 
834   /**
835    * Set this long Field. If the field is static, <code>o</code> will be
836    * ignored.
837    *
838    * @param o the object to set this Field on
839    * @param value the value to set this Field to
840    * @throws IllegalAccessException if you could not normally access this field
841    *         (i.e. it is not public)
842    * @throws IllegalArgumentException if this is not a long, float, or double
843    *         field, or if <code>o</code> is not an instance of the class
844    *         declaring this field
845    * @throws NullPointerException if <code>o</code> is null and this field
846    *         requires an instance
847    * @throws ExceptionInInitializerError if accessing a static field triggered
848    *         class initialization, which then failed
849    * @see #set(Object, Object)
850    */
setLong(Object o, long value)851   public void setLong(Object o, long value)
852     throws IllegalAccessException {
853     checkField(o, new Class[] { Long.TYPE, Float.TYPE, Double.TYPE });
854     nativeSetLong(vmData, o, value);
855   }
856 
nativeSetLong(byte[] vmData, Object o, long value)857   private native void nativeSetLong(byte[] vmData, Object o, long value)
858     throws IllegalAccessException;
859 
860 
861   /**
862    * Set this float Field. If the field is static, <code>o</code> will be
863    * ignored.
864    *
865    * @param o the object to set this Field on
866    * @param value the value to set this Field to
867    * @throws IllegalAccessException if you could not normally access this field
868    *         (i.e. it is not public)
869    * @throws IllegalArgumentException if this is not a float or long field, or
870    *         if <code>o</code> is not an instance of the class declaring this
871    *         field
872    * @throws NullPointerException if <code>o</code> is null and this field
873    *         requires an instance
874    * @throws ExceptionInInitializerError if accessing a static field triggered
875    *         class initialization, which then failed
876    * @see #set(Object, Object)
877    */
setFloat(Object o, float value)878   public void setFloat(Object o, float value)
879     throws IllegalAccessException
880   {
881     // DB: why float or long, why not double also?
882     checkField(o, new Class[] { Float.TYPE, Long.TYPE });
883     nativeSetFloat(vmData, o, value);
884   }
885 
nativeSetFloat(byte[] vmData, Object o, float value)886   private native void nativeSetFloat(byte[] vmData, Object o, float value)
887     throws IllegalAccessException;
888 
889 
890   /**
891    * Set this double Field. If the field is static, <code>o</code> will be
892    * ignored.
893    *
894    * @param o the object to set this Field on
895    * @param value the value to set this Field to
896    * @throws IllegalAccessException if you could not normally access this field
897    *         (i.e. it is not public)
898    * @throws IllegalArgumentException if this is not a double field, or if
899    *         <code>o</code> is not an instance of the class declaring this
900    *         field
901    * @throws NullPointerException if <code>o</code> is null and this field
902    *         requires an instance
903    * @throws ExceptionInInitializerError if accessing a static field triggered
904    *         class initialization, which then failed
905    * @see #set(Object, Object)
906    */
setDouble(Object o, double value)907   public void setDouble(Object o, double value)
908     throws IllegalAccessException
909   {
910     checkField(o, Double.TYPE);
911     nativeSetDouble(vmData, o, value);
912   }
913 
nativeSetDouble(byte[] vmData, Object o, double value)914   private native void nativeSetDouble(byte[] vmData, Object o, double value)
915     throws IllegalAccessException;
916 
917 }
918