KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > lang > reflect > Field


1 /*
2  * @(#)Field.java 1.42 04/05/11
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.lang.reflect;
9
10 import sun.reflect.FieldAccessor;
11 import sun.reflect.Reflection;
12 import sun.reflect.generics.repository.FieldRepository;
13 import sun.reflect.generics.factory.CoreReflectionFactory;
14 import sun.reflect.generics.factory.GenericsFactory;
15 import sun.reflect.generics.scope.ClassScope;
16 import java.lang.annotation.Annotation JavaDoc;
17 import java.util.Map JavaDoc;
18 import sun.reflect.annotation.AnnotationParser;
19
20
21 /**
22  * A <code>Field</code> provides information about, and dynamic access to, a
23  * single field of a class or an interface. The reflected field may
24  * be a class (static) field or an instance field.
25  *
26  * <p>A <code>Field</code> permits widening conversions to occur during a get or
27  * set access operation, but throws an <code>IllegalArgumentException</code> if a
28  * narrowing conversion would occur.
29  *
30  * @see Member
31  * @see java.lang.Class
32  * @see java.lang.Class#getFields()
33  * @see java.lang.Class#getField(String)
34  * @see java.lang.Class#getDeclaredFields()
35  * @see java.lang.Class#getDeclaredField(String)
36  *
37  * @author Kenneth Russell
38  * @author Nakul Saraiya
39  */

40 public final
41 class Field extends AccessibleObject JavaDoc implements Member JavaDoc {
42
43     private Class JavaDoc clazz;
44     private int slot;
45     // This is guaranteed to be interned by the VM in the 1.4
46
// reflection implementation
47
private String JavaDoc name;
48     private Class JavaDoc type;
49     private int modifiers;
50     // Generics and annotations support
51
private transient String JavaDoc signature;
52     // generic info repository; lazily initialized
53
private transient FieldRepository genericInfo;
54     private byte[] annotations;
55     // Cached field accessor created without override
56
private FieldAccessor fieldAccessor;
57     // Cached field accessor created with override
58
private FieldAccessor overrideFieldAccessor;
59     // For sharing of FieldAccessors. This branching structure is
60
// currently only two levels deep (i.e., one root Field and
61
// potentially many Field objects pointing to it.)
62
private Field JavaDoc root;
63
64     // More complicated security check cache needed here than for
65
// Class.newInstance() and Constructor.newInstance()
66
private volatile Class JavaDoc securityCheckTargetClassCache;
67
68     // Generics infrastructure
69

70     private String JavaDoc getGenericSignature() {return signature;}
71
72     // Accessor for factory
73
private GenericsFactory getFactory() {
74     Class JavaDoc<?> c = getDeclaringClass();
75     // create scope and factory
76
return CoreReflectionFactory.make(c, ClassScope.make(c));
77     }
78
79     // Accessor for generic info repository
80
private FieldRepository getGenericInfo() {
81     // lazily initialize repository if necessary
82
if (genericInfo == null) {
83         // create and cache generic info repository
84
genericInfo = FieldRepository.make(getGenericSignature(),
85                            getFactory());
86     }
87     return genericInfo; //return cached repository
88
}
89
90
91     /**
92      * Package-private constructor used by ReflectAccess to enable
93      * instantiation of these objects in Java code from the java.lang
94      * package via sun.reflect.LangReflectAccess.
95      */

96     Field(Class JavaDoc declaringClass,
97           String JavaDoc name,
98           Class JavaDoc type,
99           int modifiers,
100           int slot,
101           String JavaDoc signature,
102           byte[] annotations)
103     {
104         this.clazz = declaringClass;
105         this.name = name;
106         this.type = type;
107         this.modifiers = modifiers;
108         this.slot = slot;
109         this.signature = signature;
110         this.annotations = annotations;
111     }
112
113     /**
114      * Package-private routine (exposed to java.lang.Class via
115      * ReflectAccess) which returns a copy of this Field. The copy's
116      * "root" field points to this Field.
117      */

118     Field JavaDoc copy() {
119         // This routine enables sharing of FieldAccessor objects
120
// among Field objects which refer to the same underlying
121
// method in the VM. (All of this contortion is only necessary
122
// because of the "accessibility" bit in AccessibleObject,
123
// which implicitly requires that new java.lang.reflect
124
// objects be fabricated for each reflective call on Class
125
// objects.)
126
Field JavaDoc res = new Field JavaDoc(clazz, name, type, modifiers, slot, signature, annotations);
127         res.root = this;
128         // Might as well eagerly propagate this if already present
129
res.fieldAccessor = fieldAccessor;
130         res.overrideFieldAccessor = overrideFieldAccessor;
131         return res;
132     }
133
134     /**
135      * Returns the <code>Class</code> object representing the class or interface
136      * that declares the field represented by this <code>Field</code> object.
137      */

138     public Class JavaDoc<?> getDeclaringClass() {
139     return clazz;
140     }
141
142     /**
143      * Returns the name of the field represented by this <code>Field</code> object.
144      */

145     public String JavaDoc getName() {
146     return name;
147     }
148
149     /**
150      * Returns the Java language modifiers for the field represented
151      * by this <code>Field</code> object, as an integer. The <code>Modifier</code> class should
152      * be used to decode the modifiers.
153      *
154      * @see Modifier
155      */

156     public int getModifiers() {
157     return modifiers;
158     }
159
160     /**
161      * Returns <tt>true</tt> if this field represents an element of
162      * an enumerated type; returns <tt>false</tt> otherwise.
163      *
164      * @return <tt>true</tt> if and only if this field represents an element of
165      * an enumerated type.
166      * @since 1.5
167      */

168     public boolean isEnumConstant() {
169         return (getModifiers() & Modifier.ENUM) != 0;
170     }
171
172     /**
173      * Returns <tt>true</tt> if this field is a synthetic
174      * field; returns <tt>false</tt> otherwise.
175      *
176      * @return true if and only if this field is a synthetic
177      * field as defined by the Java Language Specification.
178      * @since 1.5
179      */

180     public boolean isSynthetic() {
181         return Modifier.isSynthetic(getModifiers());
182     }
183
184     /**
185      * Returns a <code>Class</code> object that identifies the
186      * declared type for the field represented by this
187      * <code>Field</code> object.
188      *
189      * @return a <code>Class</code> object identifying the declared
190      * type of the field represented by this object
191      */

192     public Class JavaDoc<?> getType() {
193     return type;
194     }
195
196     /**
197      * Returns a <tt>Type</tt> object that represents the declared type for
198      * the field represented by this <tt>Field</tt> object.
199      *
200      * <p>If the <tt>Type</tt> is a parameterized type, the
201      * <tt>Type</tt> object returned must accurately reflect the
202      * actual type parameters used in the source code.
203      *
204      * <p>If an the type of the underlying field is a type variable or a
205      * parameterized type, it is created. Otherwise, it is resolved.
206      *
207      * @return a <tt>Type</tt> object that represents the declared type for
208      * the field represented by this <tt>Field</tt> object
209      * @throws GenericSignatureFormatError if the generic field
210      * signature does not conform to the format specified in the Java
211      * Virtual Machine Specification, 3rd edition
212      * @throws TypeNotPresentException if the generic type
213      * signature of the underlying field refers to a non-existent
214      * type declaration
215      * @throws MalformedParameterizedTypeException if the generic
216      * signature of the underlying field refers to a parameterized type
217      * that cannot be instantiated for any reason
218      * @since 1.5
219      */

220     public Type JavaDoc getGenericType() {
221     if (getGenericSignature() != null)
222         return getGenericInfo().getGenericType();
223     else
224         return getType();
225     }
226
227
228     /**
229      * Compares this <code>Field</code> against the specified object. Returns
230      * true if the objects are the same. Two <code>Field</code> objects are the same if
231      * they were declared by the same class and have the same name
232      * and type.
233      */

234     public boolean equals(Object JavaDoc obj) {
235     if (obj != null && obj instanceof Field JavaDoc) {
236         Field JavaDoc other = (Field JavaDoc)obj;
237         return (getDeclaringClass() == other.getDeclaringClass())
238                 && (getName() == other.getName())
239         && (getType() == other.getType());
240     }
241     return false;
242     }
243
244     /**
245      * Returns a hashcode for this <code>Field</code>. This is computed as the
246      * exclusive-or of the hashcodes for the underlying field's
247      * declaring class name and its name.
248      */

249     public int hashCode() {
250     return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
251     }
252
253     /**
254      * Returns a string describing this <code>Field</code>. The format is
255      * the access modifiers for the field, if any, followed
256      * by the field type, followed by a space, followed by
257      * the fully-qualified name of the class declaring the field,
258      * followed by a period, followed by the name of the field.
259      * For example:
260      * <pre>
261      * public static final int java.lang.Thread.MIN_PRIORITY
262      * private int java.io.FileDescriptor.fd
263      * </pre>
264      *
265      * <p>The modifiers are placed in canonical order as specified by
266      * "The Java Language Specification". This is <tt>public</tt>,
267      * <tt>protected</tt> or <tt>private</tt> first, and then other
268      * modifiers in the following order: <tt>static</tt>, <tt>final</tt>,
269      * <tt>transient</tt>, <tt>volatile</tt>.
270      */

271     public String JavaDoc toString() {
272     int mod = getModifiers();
273     return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
274         + getTypeName(getType()) + " "
275         + getTypeName(getDeclaringClass()) + "."
276         + getName());
277     }
278
279     /**
280      * Returns a string describing this <code>Field</code>, including
281      * its generic type. The format is the access modifiers for the
282      * field, if any, followed by the generic field type, followed by
283      * a space, followed by the fully-qualified name of the class
284      * declaring the field, followed by a period, followed by the name
285      * of the field.
286      *
287      * <p>The modifiers are placed in canonical order as specified by
288      * "The Java Language Specification". This is <tt>public</tt>,
289      * <tt>protected</tt> or <tt>private</tt> first, and then other
290      * modifiers in the following order: <tt>static</tt>, <tt>final</tt>,
291      * <tt>transient</tt>, <tt>volatile</tt>.
292      *
293      * @return a string describing this <code>Field</code>, including
294      * its generic type
295      *
296      * @since 1.5
297      */

298     public String JavaDoc toGenericString() {
299     int mod = getModifiers();
300     Type JavaDoc fieldType = getGenericType();
301     return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
302         + ((fieldType instanceof Class JavaDoc) ?
303         getTypeName((Class JavaDoc)fieldType): fieldType.toString())+ " "
304         + getTypeName(getDeclaringClass()) + "."
305         + getName());
306     }
307
308     /**
309      * Returns the value of the field represented by this <code>Field</code>, on
310      * the specified object. The value is automatically wrapped in an
311      * object if it has a primitive type.
312      *
313      * <p>The underlying field's value is obtained as follows:
314      *
315      * <p>If the underlying field is a static field, the <code>obj</code> argument
316      * is ignored; it may be null.
317      *
318      * <p>Otherwise, the underlying field is an instance field. If the
319      * specified <code>obj</code> argument is null, the method throws a
320      * <code>NullPointerException.</code> If the specified object is not an
321      * instance of the class or interface declaring the underlying
322      * field, the method throws an <code>IllegalArgumentException</code>.
323      *
324      * <p>If this <code>Field</code> object enforces Java language access control, and
325      * the underlying field is inaccessible, the method throws an
326      * <code>IllegalAccessException</code>.
327      * If the underlying field is static, the class that declared the
328      * field is initialized if it has not already been initialized.
329      *
330      * <p>Otherwise, the value is retrieved from the underlying instance
331      * or static field. If the field has a primitive type, the value
332      * is wrapped in an object before being returned, otherwise it is
333      * returned as is.
334      *
335      * <p>If the field is hidden in the type of <code>obj</code>,
336      * the field's value is obtained according to the preceding rules.
337      *
338      * @param obj object from which the represented field's value is
339      * to be extracted
340      * @return the value of the represented field in object
341      * <tt>obj</tt>; primitive values are wrapped in an appropriate
342      * object before being returned
343      *
344      * @exception IllegalAccessException if the underlying field
345      * is inaccessible.
346      * @exception IllegalArgumentException if the specified object is not an
347      * instance of the class or interface declaring the underlying
348      * field (or a subclass or implementor thereof).
349      * @exception NullPointerException if the specified object is null
350      * and the field is an instance field.
351      * @exception ExceptionInInitializerError if the initialization provoked
352      * by this method fails.
353      */

354     public Object JavaDoc get(Object JavaDoc obj)
355         throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
356     {
357         return getFieldAccessor(obj).get(obj);
358     }
359
360     /**
361      * Gets the value of a static or instance <code>boolean</code> field.
362      *
363      * @param obj the object to extract the <code>boolean</code> value
364      * from
365      * @return the value of the <code>boolean</code> field
366      *
367      * @exception IllegalAccessException if the underlying field
368      * is inaccessible.
369      * @exception IllegalArgumentException if the specified object is not
370      * an instance of the class or interface declaring the
371      * underlying field (or a subclass or implementor
372      * thereof), or if the field value cannot be
373      * converted to the type <code>boolean</code> by a
374      * widening conversion.
375      * @exception NullPointerException if the specified object is null
376      * and the field is an instance field.
377      * @exception ExceptionInInitializerError if the initialization provoked
378      * by this method fails.
379      * @see Field#get
380      */

381     public boolean getBoolean(Object JavaDoc obj)
382     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
383     {
384         return getFieldAccessor(obj).getBoolean(obj);
385     }
386
387     /**
388      * Gets the value of a static or instance <code>byte</code> field.
389      *
390      * @param obj the object to extract the <code>byte</code> value
391      * from
392      * @return the value of the <code>byte</code> field
393      *
394      * @exception IllegalAccessException if the underlying field
395      * is inaccessible.
396      * @exception IllegalArgumentException if the specified object is not
397      * an instance of the class or interface declaring the
398      * underlying field (or a subclass or implementor
399      * thereof), or if the field value cannot be
400      * converted to the type <code>byte</code> by a
401      * widening conversion.
402      * @exception NullPointerException if the specified object is null
403      * and the field is an instance field.
404      * @exception ExceptionInInitializerError if the initialization provoked
405      * by this method fails.
406      * @see Field#get
407      */

408     public byte getByte(Object JavaDoc obj)
409     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
410     {
411         return getFieldAccessor(obj).getByte(obj);
412     }
413
414     /**
415      * Gets the value of a static or instance field of type
416      * <code>char</code> or of another primitive type convertible to
417      * type <code>char</code> via a widening conversion.
418      *
419      * @param obj the object to extract the <code>char</code> value
420      * from
421      * @return the value of the field converted to type <code>char</code>
422      *
423      * @exception IllegalAccessException if the underlying field
424      * is inaccessible.
425      * @exception IllegalArgumentException if the specified object is not
426      * an instance of the class or interface declaring the
427      * underlying field (or a subclass or implementor
428      * thereof), or if the field value cannot be
429      * converted to the type <code>char</code> by a
430      * widening conversion.
431      * @exception NullPointerException if the specified object is null
432      * and the field is an instance field.
433      * @exception ExceptionInInitializerError if the initialization provoked
434      * by this method fails.
435      * @see Field#get
436      */

437     public char getChar(Object JavaDoc obj)
438     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
439     {
440         return getFieldAccessor(obj).getChar(obj);
441     }
442
443     /**
444      * Gets the value of a static or instance field of type
445      * <code>short</code> or of another primitive type convertible to
446      * type <code>short</code> via a widening conversion.
447      *
448      * @param obj the object to extract the <code>short</code> value
449      * from
450      * @return the value of the field converted to type <code>short</code>
451      *
452      * @exception IllegalAccessException if the underlying field
453      * is inaccessible.
454      * @exception IllegalArgumentException if the specified object is not
455      * an instance of the class or interface declaring the
456      * underlying field (or a subclass or implementor
457      * thereof), or if the field value cannot be
458      * converted to the type <code>short</code> by a
459      * widening conversion.
460      * @exception NullPointerException if the specified object is null
461      * and the field is an instance field.
462      * @exception ExceptionInInitializerError if the initialization provoked
463      * by this method fails.
464      * @see Field#get
465      */

466     public short getShort(Object JavaDoc obj)
467     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
468     {
469         return getFieldAccessor(obj).getShort(obj);
470     }
471
472     /**
473      * Gets the value of a static or instance field of type
474      * <code>int</code> or of another primitive type convertible to
475      * type <code>int</code> via a widening conversion.
476      *
477      * @param obj the object to extract the <code>int</code> value
478      * from
479      * @return the value of the field converted to type <code>int</code>
480      *
481      * @exception IllegalAccessException if the underlying field
482      * is inaccessible.
483      * @exception IllegalArgumentException if the specified object is not
484      * an instance of the class or interface declaring the
485      * underlying field (or a subclass or implementor
486      * thereof), or if the field value cannot be
487      * converted to the type <code>int</code> by a
488      * widening conversion.
489      * @exception NullPointerException if the specified object is null
490      * and the field is an instance field.
491      * @exception ExceptionInInitializerError if the initialization provoked
492      * by this method fails.
493      * @see Field#get
494      */

495     public int getInt(Object JavaDoc obj)
496     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
497     {
498         return getFieldAccessor(obj).getInt(obj);
499     }
500
501     /**
502      * Gets the value of a static or instance field of type
503      * <code>long</code> or of another primitive type convertible to
504      * type <code>long</code> via a widening conversion.
505      *
506      * @param obj the object to extract the <code>long</code> value
507      * from
508      * @return the value of the field converted to type <code>long</code>
509      *
510      * @exception IllegalAccessException if the underlying field
511      * is inaccessible.
512      * @exception IllegalArgumentException if the specified object is not
513      * an instance of the class or interface declaring the
514      * underlying field (or a subclass or implementor
515      * thereof), or if the field value cannot be
516      * converted to the type <code>long</code> by a
517      * widening conversion.
518      * @exception NullPointerException if the specified object is null
519      * and the field is an instance field.
520      * @exception ExceptionInInitializerError if the initialization provoked
521      * by this method fails.
522      * @see Field#get
523      */

524     public long getLong(Object JavaDoc obj)
525     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
526     {
527         return getFieldAccessor(obj).getLong(obj);
528     }
529
530     /**
531      * Gets the value of a static or instance field of type
532      * <code>float</code> or of another primitive type convertible to
533      * type <code>float</code> via a widening conversion.
534      *
535      * @param obj the object to extract the <code>float</code> value
536      * from
537      * @return the value of the field converted to type <code>float</code>
538      *
539      * @exception IllegalAccessException if the underlying field
540      * is inaccessible.
541      * @exception IllegalArgumentException if the specified object is not
542      * an instance of the class or interface declaring the
543      * underlying field (or a subclass or implementor
544      * thereof), or if the field value cannot be
545      * converted to the type <code>float</code> by a
546      * widening conversion.
547      * @exception NullPointerException if the specified object is null
548      * and the field is an instance field.
549      * @exception ExceptionInInitializerError if the initialization provoked
550      * by this method fails.
551      * @see Field#get
552      */

553     public float getFloat(Object JavaDoc obj)
554     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
555     {
556         return getFieldAccessor(obj).getFloat(obj);
557     }
558
559     /**
560      * Gets the value of a static or instance field of type
561      * <code>double</code> or of another primitive type convertible to
562      * type <code>double</code> via a widening conversion.
563      *
564      * @param obj the object to extract the <code>double</code> value
565      * from
566      * @return the value of the field converted to type <code>double</code>
567      *
568      * @exception IllegalAccessException if the underlying field
569      * is inaccessible.
570      * @exception IllegalArgumentException if the specified object is not
571      * an instance of the class or interface declaring the
572      * underlying field (or a subclass or implementor
573      * thereof), or if the field value cannot be
574      * converted to the type <code>double</code> by a
575      * widening conversion.
576      * @exception NullPointerException if the specified object is null
577      * and the field is an instance field.
578      * @exception ExceptionInInitializerError if the initialization provoked
579      * by this method fails.
580      * @see Field#get
581      */

582     public double getDouble(Object JavaDoc obj)
583     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
584     {
585         return getFieldAccessor(obj).getDouble(obj);
586     }
587
588     /**
589      * Sets the field represented by this <code>Field</code> object on the
590      * specified object argument to the specified new value. The new
591      * value is automatically unwrapped if the underlying field has a
592      * primitive type.
593      *
594      * <p>The operation proceeds as follows:
595      *
596      * <p>If the underlying field is static, the <code>obj</code> argument is
597      * ignored; it may be null.
598      *
599      * <p>Otherwise the underlying field is an instance field. If the
600      * specified object argument is null, the method throws a
601      * <code>NullPointerException</code>. If the specified object argument is not
602      * an instance of the class or interface declaring the underlying
603      * field, the method throws an <code>IllegalArgumentException</code>.
604      *
605      * <p>If this <code>Field</code> object enforces Java language access control, and
606      * the underlying field is inaccessible, the method throws an
607      * <code>IllegalAccessException</code>.
608      *
609      * <p>If the underlying field is final, the method throws an
610      * <code>IllegalAccessException</code> unless
611      * <code>setAccessible(true)</code> has succeeded for this field
612      * and this field is non-static. Setting a final field in this way
613      * is meaningful only during deserialization or reconstruction of
614      * instances of classes with blank final fields, before they are
615      * made available for access by other parts of a program. Use in
616      * any other context may have unpredictable effects, including cases
617      * in which other parts of a program continue to use the original
618      * value of this field.
619      *
620      * <p>If the underlying field is of a primitive type, an unwrapping
621      * conversion is attempted to convert the new value to a value of
622      * a primitive type. If this attempt fails, the method throws an
623      * <code>IllegalArgumentException</code>.
624      *
625      * <p>If, after possible unwrapping, the new value cannot be
626      * converted to the type of the underlying field by an identity or
627      * widening conversion, the method throws an
628      * <code>IllegalArgumentException</code>.
629      *
630      * <p>If the underlying field is static, the class that declared the
631      * field is initialized if it has not already been initialized.
632      *
633      * <p>The field is set to the possibly unwrapped and widened new value.
634      *
635      * <p>If the field is hidden in the type of <code>obj</code>,
636      * the field's value is set according to the preceding rules.
637      *
638      * @param obj the object whose field should be modified
639      * @param value the new value for the field of <code>obj</code>
640      * being modified
641      *
642      * @exception IllegalAccessException if the underlying field
643      * is inaccessible.
644      * @exception IllegalArgumentException if the specified object is not an
645      * instance of the class or interface declaring the underlying
646      * field (or a subclass or implementor thereof),
647      * or if an unwrapping conversion fails.
648      * @exception NullPointerException if the specified object is null
649      * and the field is an instance field.
650      * @exception ExceptionInInitializerError if the initialization provoked
651      * by this method fails.
652      */

653     public void set(Object JavaDoc obj, Object JavaDoc value)
654     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
655     {
656         getFieldAccessor(obj).set(obj, value);
657     }
658
659     /**
660      * Sets the value of a field as a <code>boolean</code> on the specified object.
661      * This method is equivalent to
662      * <code>set(obj, zObj)</code>,
663      * where <code>zObj</code> is a <code>Boolean</code> object and
664      * <code>zObj.booleanValue() == z</code>.
665      *
666      * @param obj the object whose field should be modified
667      * @param z the new value for the field of <code>obj</code>
668      * being modified
669      *
670      * @exception IllegalAccessException if the underlying field
671      * is inaccessible.
672      * @exception IllegalArgumentException if the specified object is not an
673      * instance of the class or interface declaring the underlying
674      * field (or a subclass or implementor thereof),
675      * or if an unwrapping conversion fails.
676      * @exception NullPointerException if the specified object is null
677      * and the field is an instance field.
678      * @exception ExceptionInInitializerError if the initialization provoked
679      * by this method fails.
680      * @see Field#set
681      */

682     public void setBoolean(Object JavaDoc obj, boolean z)
683     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
684     {
685         getFieldAccessor(obj).setBoolean(obj, z);
686     }
687
688     /**
689      * Sets the value of a field as a <code>byte</code> on the specified object.
690      * This method is equivalent to
691      * <code>set(obj, bObj)</code>,
692      * where <code>bObj</code> is a <code>Byte</code> object and
693      * <code>bObj.byteValue() == b</code>.
694      *
695      * @param obj the object whose field should be modified
696      * @param b the new value for the field of <code>obj</code>
697      * being modified
698      *
699      * @exception IllegalAccessException if the underlying field
700      * is inaccessible.
701      * @exception IllegalArgumentException if the specified object is not an
702      * instance of the class or interface declaring the underlying
703      * field (or a subclass or implementor thereof),
704      * or if an unwrapping conversion fails.
705      * @exception NullPointerException if the specified object is null
706      * and the field is an instance field.
707      * @exception ExceptionInInitializerError if the initialization provoked
708      * by this method fails.
709      * @see Field#set
710      */

711     public void setByte(Object JavaDoc obj, byte b)
712     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
713     {
714         getFieldAccessor(obj).setByte(obj, b);
715     }
716
717     /**
718      * Sets the value of a field as a <code>char</code> on the specified object.
719      * This method is equivalent to
720      * <code>set(obj, cObj)</code>,
721      * where <code>cObj</code> is a <code>Character</code> object and
722      * <code>cObj.charValue() == c</code>.
723      *
724      * @param obj the object whose field should be modified
725      * @param c the new value for the field of <code>obj</code>
726      * being modified
727      *
728      * @exception IllegalAccessException if the underlying field
729      * is inaccessible.
730      * @exception IllegalArgumentException if the specified object is not an
731      * instance of the class or interface declaring the underlying
732      * field (or a subclass or implementor thereof),
733      * or if an unwrapping conversion fails.
734      * @exception NullPointerException if the specified object is null
735      * and the field is an instance field.
736      * @exception ExceptionInInitializerError if the initialization provoked
737      * by this method fails.
738      * @see Field#set
739      */

740     public void setChar(Object JavaDoc obj, char c)
741     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
742     {
743         getFieldAccessor(obj).setChar(obj, c);
744     }
745
746     /**
747      * Sets the value of a field as a <code>short</code> on the specified object.
748      * This method is equivalent to
749      * <code>set(obj, sObj)</code>,
750      * where <code>sObj</code> is a <code>Short</code> object and
751      * <code>sObj.shortValue() == s</code>.
752      *
753      * @param obj the object whose field should be modified
754      * @param s the new value for the field of <code>obj</code>
755      * being modified
756      *
757      * @exception IllegalAccessException if the underlying field
758      * is inaccessible.
759      * @exception IllegalArgumentException if the specified object is not an
760      * instance of the class or interface declaring the underlying
761      * field (or a subclass or implementor thereof),
762      * or if an unwrapping conversion fails.
763      * @exception NullPointerException if the specified object is null
764      * and the field is an instance field.
765      * @exception ExceptionInInitializerError if the initialization provoked
766      * by this method fails.
767      * @see Field#set
768      */

769     public void setShort(Object JavaDoc obj, short s)
770     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
771     {
772         getFieldAccessor(obj).setShort(obj, s);
773     }
774
775     /**
776      * Sets the value of a field as an <code>int</code> on the specified object.
777      * This method is equivalent to
778      * <code>set(obj, iObj)</code>,
779      * where <code>iObj</code> is a <code>Integer</code> object and
780      * <code>iObj.intValue() == i</code>.
781      *
782      * @param obj the object whose field should be modified
783      * @param i the new value for the field of <code>obj</code>
784      * being modified
785      *
786      * @exception IllegalAccessException if the underlying field
787      * is inaccessible.
788      * @exception IllegalArgumentException if the specified object is not an
789      * instance of the class or interface declaring the underlying
790      * field (or a subclass or implementor thereof),
791      * or if an unwrapping conversion fails.
792      * @exception NullPointerException if the specified object is null
793      * and the field is an instance field.
794      * @exception ExceptionInInitializerError if the initialization provoked
795      * by this method fails.
796      * @see Field#set
797      */

798     public void setInt(Object JavaDoc obj, int i)
799     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
800     {
801         getFieldAccessor(obj).setInt(obj, i);
802     }
803
804     /**
805      * Sets the value of a field as a <code>long</code> on the specified object.
806      * This method is equivalent to
807      * <code>set(obj, lObj)</code>,
808      * where <code>lObj</code> is a <code>Long</code> object and
809      * <code>lObj.longValue() == l</code>.
810      *
811      * @param obj the object whose field should be modified
812      * @param l the new value for the field of <code>obj</code>
813      * being modified
814      *
815      * @exception IllegalAccessException if the underlying field
816      * is inaccessible.
817      * @exception IllegalArgumentException if the specified object is not an
818      * instance of the class or interface declaring the underlying
819      * field (or a subclass or implementor thereof),
820      * or if an unwrapping conversion fails.
821      * @exception NullPointerException if the specified object is null
822      * and the field is an instance field.
823      * @exception ExceptionInInitializerError if the initialization provoked
824      * by this method fails.
825      * @see Field#set
826      */

827     public void setLong(Object JavaDoc obj, long l)
828     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
829     {
830         getFieldAccessor(obj).setLong(obj, l);
831     }
832
833     /**
834      * Sets the value of a field as a <code>float</code> on the specified object.
835      * This method is equivalent to
836      * <code>set(obj, fObj)</code>,
837      * where <code>fObj</code> is a <code>Float</code> object and
838      * <code>fObj.floatValue() == f</code>.
839      *
840      * @param obj the object whose field should be modified
841      * @param f the new value for the field of <code>obj</code>
842      * being modified
843      *
844      * @exception IllegalAccessException if the underlying field
845      * is inaccessible.
846      * @exception IllegalArgumentException if the specified object is not an
847      * instance of the class or interface declaring the underlying
848      * field (or a subclass or implementor thereof),
849      * or if an unwrapping conversion fails.
850      * @exception NullPointerException if the specified object is null
851      * and the field is an instance field.
852      * @exception ExceptionInInitializerError if the initialization provoked
853      * by this method fails.
854      * @see Field#set
855      */

856     public void setFloat(Object JavaDoc obj, float f)
857     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
858     {
859         getFieldAccessor(obj).setFloat(obj, f);
860     }
861
862     /**
863      * Sets the value of a field as a <code>double</code> on the specified object.
864      * This method is equivalent to
865      * <code>set(obj, dObj)</code>,
866      * where <code>dObj</code> is a <code>Double</code> object and
867      * <code>dObj.doubleValue() == d</code>.
868      *
869      * @param obj the object whose field should be modified
870      * @param d the new value for the field of <code>obj</code>
871      * being modified
872      *
873      * @exception IllegalAccessException if the underlying field
874      * is inaccessible.
875      * @exception IllegalArgumentException if the specified object is not an
876      * instance of the class or interface declaring the underlying
877      * field (or a subclass or implementor thereof),
878      * or if an unwrapping conversion fails.
879      * @exception NullPointerException if the specified object is null
880      * and the field is an instance field.
881      * @exception ExceptionInInitializerError if the initialization provoked
882      * by this method fails.
883      * @see Field#set
884      */

885     public void setDouble(Object JavaDoc obj, double d)
886     throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc
887     {
888         getFieldAccessor(obj).setDouble(obj, d);
889     }
890
891     // Convenience routine which performs security checks
892
private FieldAccessor getFieldAccessor(Object JavaDoc obj)
893         throws IllegalAccessException JavaDoc
894     {
895         doSecurityCheck(obj);
896         boolean ov = override;
897         FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor;
898         return (a != null)? a : acquireFieldAccessor(ov);
899     }
900
901     // NOTE that there is no synchronization used here. It is correct
902
// (though not efficient) to generate more than one FieldAccessor
903
// for a given Field. However, avoiding synchronization will
904
// probably make the implementation more scalable.
905
private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) {
906         // First check to see if one has been created yet, and take it
907
// if so
908
FieldAccessor tmp = null;
909         if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck);
910         if (tmp != null) {
911             if (overrideFinalCheck)
912                 overrideFieldAccessor = tmp;
913             else
914                 fieldAccessor = tmp;
915         } else {
916             // Otherwise fabricate one and propagate it up to the root
917
tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
918             setFieldAccessor(tmp, overrideFinalCheck);
919         }
920         return tmp;
921     }
922
923     // Returns FieldAccessor for this Field object, not looking up
924
// the chain to the root
925
private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) {
926         return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor;
927     }
928
929     // Sets the FieldAccessor for this Field object and
930
// (recursively) its root
931
private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) {
932         if (overrideFinalCheck)
933             overrideFieldAccessor = accessor;
934         else
935             fieldAccessor = accessor;
936         // Propagate up
937
if (root != null) {
938             root.setFieldAccessor(accessor, overrideFinalCheck);
939         }
940     }
941
942     // NOTE: be very careful if you change the stack depth of this
943
// routine. The depth of the "getCallerClass" call is hardwired so
944
// that the compiler can have an easier time if this gets inlined.
945
private void doSecurityCheck(Object JavaDoc obj) throws IllegalAccessException JavaDoc {
946         if (!override) {
947             if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
948                 Class JavaDoc caller = Reflection.getCallerClass(4);
949                 Class JavaDoc targetClass = ((obj == null || !Modifier.isProtected(modifiers))
950                                      ? clazz
951                                      : obj.getClass());
952                 if (securityCheckCache != caller ||
953                     targetClass != securityCheckTargetClassCache) {
954                     Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
955                     securityCheckCache = caller;
956                     securityCheckTargetClassCache = targetClass;
957                 }
958             }
959         }
960     }
961
962     /*
963      * Utility routine to paper over array type names
964      */

965     static String JavaDoc getTypeName(Class JavaDoc type) {
966     if (type.isArray()) {
967         try {
968         Class JavaDoc cl = type;
969         int dimensions = 0;
970         while (cl.isArray()) {
971             dimensions++;
972             cl = cl.getComponentType();
973         }
974         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
975         sb.append(cl.getName());
976         for (int i = 0; i < dimensions; i++) {
977             sb.append("[]");
978         }
979         return sb.toString();
980         } catch (Throwable JavaDoc e) { /*FALLTHRU*/ }
981     }
982     return type.getName();
983     }
984
985     public <T extends Annotation JavaDoc> T getAnnotation(Class JavaDoc<T> annotationClass) {
986         if (annotationClass == null)
987             throw new NullPointerException JavaDoc();
988
989         return (T) declaredAnnotations().get(annotationClass);
990     }
991
992     private static final Annotation JavaDoc[] EMPTY_ANNOTATION_ARRAY=new Annotation JavaDoc[0];
993
994     public Annotation JavaDoc[] getDeclaredAnnotations() {
995         return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
996     }
997
998     private transient Map JavaDoc<Class JavaDoc, Annotation JavaDoc> declaredAnnotations;
999
1000    private synchronized Map JavaDoc<Class JavaDoc, Annotation JavaDoc> declaredAnnotations() {
1001        if (declaredAnnotations == null) {
1002            declaredAnnotations = AnnotationParser.parseAnnotations(
1003                annotations, sun.misc.SharedSecrets.getJavaLangAccess().
1004                getConstantPool(getDeclaringClass()),
1005                getDeclaringClass());
1006        }
1007        return declaredAnnotations;
1008    }
1009}
1010
Popular Tags