1 /* java.lang.reflect.Field - reflection of Java fields
2    Copyright (C) 1998, 2001, 2005, 2008 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package java.lang.reflect;
40 
41 import gnu.java.lang.ClassHelper;
42 import gnu.java.lang.CPStringBuilder;
43 
44 import gnu.java.lang.reflect.FieldSignatureParser;
45 
46 import java.lang.annotation.Annotation;
47 
48 /**
49  * The Field class represents a member variable of a class. It also allows
50  * dynamic access to a member, via reflection. This works for both
51  * static and instance fields. Operations on Field objects know how to
52  * do widening conversions, but throw {@link IllegalArgumentException} if
53  * a narrowing conversion would be necessary. You can query for information
54  * on this Field regardless of location, but get and set access may be limited
55  * by Java language access controls. If you can't do it in the compiler, you
56  * can't normally do it here either.<p>
57  *
58  * <B>Note:</B> This class returns and accepts types as Classes, even
59  * primitive types; there are Class types defined that represent each
60  * different primitive type.  They are <code>java.lang.Boolean.TYPE,
61  * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
62  * byte.class</code>, etc.  These are not to be confused with the
63  * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
64  * real classes.<p>
65  *
66  * Also note that this is not a serializable class.  It is entirely feasible
67  * to make it serializable using the Externalizable interface, but this is
68  * on Sun, not me.
69  *
70  * @author John Keiser
71  * @author Eric Blake <ebb9@email.byu.edu>
72  * @see Member
73  * @see Class
74  * @see Class#getField(String)
75  * @see Class#getDeclaredField(String)
76  * @see Class#getFields()
77  * @see Class#getDeclaredFields()
78  * @since 1.1
79  * @status updated to 1.4
80  */
81 public final class Field
82 extends AccessibleObject implements Member
83 {
84   static final int FIELD_MODIFIERS
85     = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
86       | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
87       | Modifier.VOLATILE;
88 
89   private FieldSignatureParser p;
90 
91   VMField f;
92 
93   /**
94    * This class is uninstantiable outside the package.
95    */
Field(VMField f)96   Field(VMField f)
97   {
98     this.f = f;
99     f.f = this;
100   }
101 
102   /**
103    * Gets the class that declared this field, or the class where this field
104    * is a non-inherited member.
105    * @return the class that declared this member
106    */
getDeclaringClass()107   public Class<?> getDeclaringClass()
108   {
109     return (Class<?>) f.getDeclaringClass();
110   }
111 
112   /**
113    * Gets the name of this field.
114    * @return the name of this field
115    */
getName()116   public String getName()
117   {
118     return f.getName();
119   }
120 
121   /**
122    * Gets the modifiers this field uses.  Use the <code>Modifier</code>
123    * class to interpret the values.  A field can only have a subset of the
124    * following modifiers: public, private, protected, static, final,
125    * transient, and volatile.
126    *
127    * @return an integer representing the modifiers to this Member
128    * @see Modifier
129    */
getModifiers()130   public int getModifiers()
131   {
132     return f.getModifiersInternal() & FIELD_MODIFIERS;
133   }
134 
135   /**
136    * Return true if this field is synthetic, false otherwise.
137    * @since 1.5
138    */
isSynthetic()139   public boolean isSynthetic()
140   {
141     return (f.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
142   }
143 
144   /**
145    * Return true if this field represents an enum constant,
146    * false otherwise.
147    * @since 1.5
148    */
isEnumConstant()149   public boolean isEnumConstant()
150   {
151     return (f.getModifiersInternal() & Modifier.ENUM) != 0;
152   }
153 
154   /**
155    * Gets the type of this field.
156    * @return the type of this field
157    */
getType()158   public Class<?> getType()
159   {
160     return f.getType();
161   }
162 
163   /**
164    * Compare two objects to see if they are semantically equivalent.
165    * Two Fields are semantically equivalent if they have the same declaring
166    * class, name, and type. Since you can't creat a Field except through
167    * the VM, this is just the == relation.
168    *
169    * @param o the object to compare to
170    * @return <code>true</code> if they are equal; <code>false</code> if not
171    */
equals(Object o)172   public boolean equals(Object o)
173   {
174     return f.equals(o);
175   }
176 
177   /**
178    * Get the hash code for the Field. The Field hash code is the hash code
179    * of its name XOR'd with the hash code of its class name.
180    *
181    * @return the hash code for the object.
182    */
hashCode()183   public int hashCode()
184   {
185     return f.getDeclaringClass().getName().hashCode() ^ f.getName().hashCode();
186   }
187 
188   /**
189    * Get a String representation of the Field. A Field's String
190    * representation is "&lt;modifiers&gt; &lt;type&gt;
191    * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
192    * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
193    *
194    * @return the String representation of the Field
195    */
toString()196   public String toString()
197   {
198     // 64 is a reasonable buffer initial size for field
199     CPStringBuilder sb = new CPStringBuilder(64);
200     Modifier.toString(getModifiers(), sb).append(' ');
201     sb.append(ClassHelper.getUserName(getType())).append(' ');
202     sb.append(getDeclaringClass().getName()).append('.');
203     sb.append(getName());
204     return sb.toString();
205   }
206 
toGenericString()207   public String toGenericString()
208   {
209     CPStringBuilder sb = new CPStringBuilder(64);
210     Modifier.toString(getModifiers(), sb).append(' ');
211     sb.append(getGenericType()).append(' ');
212     sb.append(getDeclaringClass().getName()).append('.');
213     sb.append(getName());
214     return sb.toString();
215   }
216 
217   /**
218    * Get the value of this Field.  If it is primitive, it will be wrapped
219    * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
220    *
221    * If the field is static, <code>o</code> will be ignored. Otherwise, if
222    * <code>o</code> is null, you get a <code>NullPointerException</code>,
223    * and if it is incompatible with the declaring class of the field, you
224    * get an <code>IllegalArgumentException</code>.<p>
225    *
226    * Next, if this Field enforces access control, your runtime context is
227    * evaluated, and you may have an <code>IllegalAccessException</code> if
228    * you could not access this field in similar compiled code. If the field
229    * is static, and its class is uninitialized, you trigger class
230    * initialization, which may end in a
231    * <code>ExceptionInInitializerError</code>.<p>
232    *
233    * Finally, the field is accessed, and primitives are wrapped (but not
234    * necessarily in new objects). This method accesses the field of the
235    * declaring class, even if the instance passed in belongs to a subclass
236    * which declares another field to hide this one.
237    *
238    * @param o the object to get the value of this Field from
239    * @return the value of the Field
240    * @throws IllegalAccessException if you could not normally access this field
241    *         (i.e. it is not public)
242    * @throws IllegalArgumentException if <code>o</code> is not an instance of
243    *         the class or interface declaring this field
244    * @throws NullPointerException if <code>o</code> is null and this field
245    *         requires an instance
246    * @throws ExceptionInInitializerError if accessing a static field triggered
247    *         class initialization, which then failed
248    * @see #getBoolean(Object)
249    * @see #getByte(Object)
250    * @see #getChar(Object)
251    * @see #getShort(Object)
252    * @see #getInt(Object)
253    * @see #getLong(Object)
254    * @see #getFloat(Object)
255    * @see #getDouble(Object)
256    */
get(Object o)257   public Object get(Object o)
258     throws IllegalAccessException
259   {
260     return f.get(o);
261   }
262 
263   /**
264    * Get the value of this boolean Field. If the field is static,
265    * <code>o</code> will be ignored.
266    *
267    * @param o the object to get the value of this Field from
268    * @return the value of the Field
269    * @throws IllegalAccessException if you could not normally access this field
270    *         (i.e. it is not public)
271    * @throws IllegalArgumentException if this is not a boolean field of
272    *         <code>o</code>, or if <code>o</code> is not an instance of the
273    *         declaring class of this field
274    * @throws NullPointerException if <code>o</code> is null and this field
275    *         requires an instance
276    * @throws ExceptionInInitializerError if accessing a static field triggered
277    *         class initialization, which then failed
278    * @see #get(Object)
279    */
getBoolean(Object o)280   public boolean getBoolean(Object o)
281     throws IllegalAccessException
282   {
283     return f.getBoolean(o);
284   }
285 
286   /**
287    * Get the value of this byte Field. If the field is static,
288    * <code>o</code> will be ignored.
289    *
290    * @param o the object to get the value of this Field from
291    * @return the value of the Field
292    * @throws IllegalAccessException if you could not normally access this field
293    *         (i.e. it is not public)
294    * @throws IllegalArgumentException if this is not a byte field of
295    *         <code>o</code>, or if <code>o</code> is not an instance of the
296    *         declaring class of this field
297    * @throws NullPointerException if <code>o</code> is null and this field
298    *         requires an instance
299    * @throws ExceptionInInitializerError if accessing a static field triggered
300    *         class initialization, which then failed
301    * @see #get(Object)
302    */
getByte(Object o)303   public byte getByte(Object o)
304     throws IllegalAccessException
305   {
306     return f.getByte(o);
307   }
308 
309   /**
310    * Get the value of this Field as a char. If the field is static,
311    * <code>o</code> will be ignored.
312    *
313    * @throws IllegalAccessException if you could not normally access this field
314    *         (i.e. it is not public)
315    * @throws IllegalArgumentException if this is not a char field of
316    *         <code>o</code>, or if <code>o</code> is not an instance
317    *         of the declaring class of this field
318    * @throws NullPointerException if <code>o</code> is null and this field
319    *         requires an instance
320    * @throws ExceptionInInitializerError if accessing a static field triggered
321    *         class initialization, which then failed
322    * @see #get(Object)
323    */
getChar(Object o)324   public char getChar(Object o)
325     throws IllegalAccessException
326   {
327     return f.getChar(o);
328   }
329 
330   /**
331    * Get the value of this Field as a short. If the field is static,
332    * <code>o</code> will be ignored.
333    *
334    * @param o the object to get the value of this Field from
335    * @return the value of the Field
336    * @throws IllegalAccessException if you could not normally access this field
337    *         (i.e. it is not public)
338    * @throws IllegalArgumentException if this is not a byte or short
339    *         field of <code>o</code>, or if <code>o</code> is not an instance
340    *         of the declaring class of this field
341    * @throws NullPointerException if <code>o</code> is null and this field
342    *         requires an instance
343    * @throws ExceptionInInitializerError if accessing a static field triggered
344    *         class initialization, which then failed
345    * @see #get(Object)
346    */
getShort(Object o)347   public short getShort(Object o)
348     throws IllegalAccessException
349   {
350     return f.getShort(o);
351   }
352 
353   /**
354    * Get the value of this Field as an int. If the field is static,
355    * <code>o</code> will be ignored.
356    *
357    * @param o the object to get the value of this Field from
358    * @return the value of the Field
359    * @throws IllegalAccessException if you could not normally access this field
360    *         (i.e. it is not public)
361    * @throws IllegalArgumentException if this is not a byte, short, char, or
362    *         int field of <code>o</code>, or if <code>o</code> is not an
363    *         instance of the declaring class of this field
364    * @throws NullPointerException if <code>o</code> is null and this field
365    *         requires an instance
366    * @throws ExceptionInInitializerError if accessing a static field triggered
367    *         class initialization, which then failed
368    * @see #get(Object)
369    */
getInt(Object o)370   public int getInt(Object o)
371     throws IllegalAccessException
372   {
373     return f.getInt(o);
374   }
375 
376   /**
377    * Get the value of this Field as a long. If the field is static,
378    * <code>o</code> will be ignored.
379    *
380    * @param o the object to get the value of this Field from
381    * @return the value of the Field
382    * @throws IllegalAccessException if you could not normally access this field
383    *         (i.e. it is not public)
384    * @throws IllegalArgumentException if this is not a byte, short, char, int,
385    *         or long field of <code>o</code>, or if <code>o</code> is not an
386    *         instance of the declaring class of this field
387    * @throws NullPointerException if <code>o</code> is null and this field
388    *         requires an instance
389    * @throws ExceptionInInitializerError if accessing a static field triggered
390    *         class initialization, which then failed
391    * @see #get(Object)
392    */
getLong(Object o)393   public long getLong(Object o)
394     throws IllegalAccessException
395   {
396     return f.getLong(o);
397   }
398 
399   /**
400    * Get the value of this Field as a float. If the field is static,
401    * <code>o</code> will be ignored.
402    *
403    * @param o the object to get the value of this Field from
404    * @return the value of the Field
405    * @throws IllegalAccessException if you could not normally access this field
406    *         (i.e. it is not public)
407    * @throws IllegalArgumentException if this is not a byte, short, char, int,
408    *         long, or float field of <code>o</code>, or if <code>o</code> is
409    *         not an instance of the declaring class of this field
410    * @throws NullPointerException if <code>o</code> is null and this field
411    *         requires an instance
412    * @throws ExceptionInInitializerError if accessing a static field triggered
413    *         class initialization, which then failed
414    * @see #get(Object)
415    */
getFloat(Object o)416   public float getFloat(Object o)
417     throws IllegalAccessException
418   {
419     return f.getFloat(o);
420   }
421 
422   /**
423    * Get the value of this Field as a double. If the field is static,
424    * <code>o</code> will be ignored.
425    *
426    * @param o the object to get the value of this Field from
427    * @return the value of the Field
428    * @throws IllegalAccessException if you could not normally access this field
429    *         (i.e. it is not public)
430    * @throws IllegalArgumentException if this is not a byte, short, char, int,
431    *         long, float, or double field of <code>o</code>, or if
432    *         <code>o</code> is not an instance of the declaring class of this
433    *         field
434    * @throws NullPointerException if <code>o</code> is null and this field
435    *         requires an instance
436    * @throws ExceptionInInitializerError if accessing a static field triggered
437    *         class initialization, which then failed
438    * @see #get(Object)
439    */
getDouble(Object o)440   public double getDouble(Object o)
441     throws IllegalAccessException
442   {
443     return f.getDouble(o);
444   }
445 
446   /**
447    * Set the value of this Field.  If it is a primitive field, the value
448    * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
449    *
450    * If the field is static, <code>o</code> will be ignored. Otherwise, if
451    * <code>o</code> is null, you get a <code>NullPointerException</code>,
452    * and if it is incompatible with the declaring class of the field, you
453    * get an <code>IllegalArgumentException</code>.<p>
454    *
455    * Next, if this Field enforces access control, your runtime context is
456    * evaluated, and you may have an <code>IllegalAccessException</code> if
457    * you could not access this field in similar compiled code. This also
458    * occurs whether or not there is access control if the field is final.
459    * If the field is primitive, and unwrapping your argument fails, you will
460    * get an <code>IllegalArgumentException</code>; likewise, this error
461    * happens if <code>value</code> cannot be cast to the correct object type.
462    * If the field is static, and its class is uninitialized, you trigger class
463    * initialization, which may end in a
464    * <code>ExceptionInInitializerError</code>.<p>
465    *
466    * Finally, the field is set with the widened value. This method accesses
467    * the field of the declaring class, even if the instance passed in belongs
468    * to a subclass which declares another field to hide this one.
469    *
470    * @param o the object to set this Field on
471    * @param value the value to set this Field to
472    * @throws IllegalAccessException if you could not normally access this field
473    *         (i.e. it is not public)
474    * @throws IllegalArgumentException if <code>value</code> cannot be
475    *         converted by a widening conversion to the underlying type of
476    *         the Field, or if <code>o</code> is not an instance of the class
477    *         declaring this field
478    * @throws NullPointerException if <code>o</code> is null and this field
479    *         requires an instance
480    * @throws ExceptionInInitializerError if accessing a static field triggered
481    *         class initialization, which then failed
482    * @see #setBoolean(Object, boolean)
483    * @see #setByte(Object, byte)
484    * @see #setChar(Object, char)
485    * @see #setShort(Object, short)
486    * @see #setInt(Object, int)
487    * @see #setLong(Object, long)
488    * @see #setFloat(Object, float)
489    * @see #setDouble(Object, double)
490    */
set(Object o, Object value)491   public void set(Object o, Object value)
492     throws IllegalAccessException
493   {
494     f.set(o, value);
495   }
496 
497   /**
498    * Set this boolean Field. If the field is static, <code>o</code> will be
499    * ignored.
500    *
501    * @param o the object to set this Field on
502    * @param value the value to set this Field to
503    * @throws IllegalAccessException if you could not normally access this field
504    *         (i.e. it is not public)
505    * @throws IllegalArgumentException if this is not a boolean field, or if
506    *         <code>o</code> is not an instance of the class declaring this
507    *         field
508    * @throws NullPointerException if <code>o</code> is null and this field
509    *         requires an instance
510    * @throws ExceptionInInitializerError if accessing a static field triggered
511    *         class initialization, which then failed
512    * @see #set(Object, Object)
513    */
setBoolean(Object o, boolean value)514   public void setBoolean(Object o, boolean value)
515     throws IllegalAccessException
516   {
517     f.setBoolean(o, value);
518   }
519 
520   /**
521    * Set this byte Field. If the field is static, <code>o</code> will be
522    * ignored.
523    *
524    * @param o the object to set this Field on
525    * @param value the value to set this Field to
526    * @throws IllegalAccessException if you could not normally access this field
527    *         (i.e. it is not public)
528    * @throws IllegalArgumentException if this is not a byte, short, int, long,
529    *         float, or double field, or if <code>o</code> is not an instance
530    *         of the class declaring this field
531    * @throws NullPointerException if <code>o</code> is null and this field
532    *         requires an instance
533    * @throws ExceptionInInitializerError if accessing a static field triggered
534    *         class initialization, which then failed
535    * @see #set(Object, Object)
536    */
setByte(Object o, byte value)537   public void setByte(Object o, byte value)
538     throws IllegalAccessException
539   {
540     f.setByte(o, value);
541   }
542 
543   /**
544    * Set this char Field. If the field is static, <code>o</code> will be
545    * ignored.
546    *
547    * @param o the object to set this Field on
548    * @param value the value to set this Field to
549    * @throws IllegalAccessException if you could not normally access this field
550    *         (i.e. it is not public)
551    * @throws IllegalArgumentException if this is not a char, int, long,
552    *         float, or double field, or if <code>o</code> is not an instance
553    *         of the class declaring this field
554    * @throws NullPointerException if <code>o</code> is null and this field
555    *         requires an instance
556    * @throws ExceptionInInitializerError if accessing a static field triggered
557    *         class initialization, which then failed
558    * @see #set(Object, Object)
559    */
setChar(Object o, char value)560   public void setChar(Object o, char value)
561     throws IllegalAccessException
562   {
563     f.setChar(o, value);
564   }
565 
566   /**
567    * Set this short Field. If the field is static, <code>o</code> will be
568    * ignored.
569    *
570    * @param o the object to set this Field on
571    * @param value the value to set this Field to
572    * @throws IllegalAccessException if you could not normally access this field
573    *         (i.e. it is not public)
574    * @throws IllegalArgumentException if this is not a short, int, long,
575    *         float, or double field, or if <code>o</code> is not an instance
576    *         of the class declaring this field
577    * @throws NullPointerException if <code>o</code> is null and this field
578    *         requires an instance
579    * @throws ExceptionInInitializerError if accessing a static field triggered
580    *         class initialization, which then failed
581    * @see #set(Object, Object)
582    */
setShort(Object o, short value)583   public void setShort(Object o, short value)
584     throws IllegalAccessException
585   {
586     f.setShort(o, value);
587   }
588 
589   /**
590    * Set this int Field. If the field is static, <code>o</code> will be
591    * ignored.
592    *
593    * @param o the object to set this Field on
594    * @param value the value to set this Field to
595    * @throws IllegalAccessException if you could not normally access this field
596    *         (i.e. it is not public)
597    * @throws IllegalArgumentException if this is not an int, long, float, or
598    *         double field, or if <code>o</code> is not an instance of the
599    *         class declaring this field
600    * @throws NullPointerException if <code>o</code> is null and this field
601    *         requires an instance
602    * @throws ExceptionInInitializerError if accessing a static field triggered
603    *         class initialization, which then failed
604    * @see #set(Object, Object)
605    */
setInt(Object o, int value)606   public void setInt(Object o, int value)
607     throws IllegalAccessException
608   {
609     f.setInt(o, value);
610   }
611 
612   /**
613    * Set this long Field. If the field is static, <code>o</code> will be
614    * ignored.
615    *
616    * @param o the object to set this Field on
617    * @param value the value to set this Field to
618    * @throws IllegalAccessException if you could not normally access this field
619    *         (i.e. it is not public)
620    * @throws IllegalArgumentException if this is not a long, float, or double
621    *         field, or if <code>o</code> is not an instance of the class
622    *         declaring this field
623    * @throws NullPointerException if <code>o</code> is null and this field
624    *         requires an instance
625    * @throws ExceptionInInitializerError if accessing a static field triggered
626    *         class initialization, which then failed
627    * @see #set(Object, Object)
628    */
setLong(Object o, long value)629   public void setLong(Object o, long value)
630     throws IllegalAccessException
631   {
632     f.setLong(o, value);
633   }
634 
635   /**
636    * Set this float Field. If the field is static, <code>o</code> will be
637    * ignored.
638    *
639    * @param o the object to set this Field on
640    * @param value the value to set this Field to
641    * @throws IllegalAccessException if you could not normally access this field
642    *         (i.e. it is not public)
643    * @throws IllegalArgumentException if this is not a float or long field, or
644    *         if <code>o</code> is not an instance of the class declaring this
645    *         field
646    * @throws NullPointerException if <code>o</code> is null and this field
647    *         requires an instance
648    * @throws ExceptionInInitializerError if accessing a static field triggered
649    *         class initialization, which then failed
650    * @see #set(Object, Object)
651    */
setFloat(Object o, float value)652   public void setFloat(Object o, float value)
653     throws IllegalAccessException
654   {
655     f.setFloat(o, value);
656   }
657 
658   /**
659    * Set this double Field. If the field is static, <code>o</code> will be
660    * ignored.
661    *
662    * @param o the object to set this Field on
663    * @param value the value to set this Field to
664    * @throws IllegalAccessException if you could not normally access this field
665    *         (i.e. it is not public)
666    * @throws IllegalArgumentException if this is not a double field, or if
667    *         <code>o</code> is not an instance of the class declaring this
668    *         field
669    * @throws NullPointerException if <code>o</code> is null and this field
670    *         requires an instance
671    * @throws ExceptionInInitializerError if accessing a static field triggered
672    *         class initialization, which then failed
673    * @see #set(Object, Object)
674    */
setDouble(Object o, double value)675   public void setDouble(Object o, double value)
676     throws IllegalAccessException
677   {
678     f.setDouble(o, value);
679   }
680 
681   /**
682    * Return the generic type of the field. If the field type is not a generic
683    * type, the method returns the same as <code>getType()</code>.
684    *
685    * @throws GenericSignatureFormatError if the generic signature does
686    *         not conform to the format specified in the Virtual Machine
687    *         specification, version 3.
688    * @since 1.5
689    */
getGenericType()690   public Type getGenericType()
691   {
692     if (p == null)
693       {
694         String signature = f.getSignature();
695         if (signature == null)
696           return getType();
697         p = new FieldSignatureParser(getDeclaringClass(),
698                                      signature);
699       }
700     return p.getFieldType();
701   }
702 
703   /**
704    * Returns the element's annotation for the specified annotation type,
705    * or <code>null</code> if no such annotation exists.
706    *
707    * @param annotationClass the type of annotation to look for.
708    * @return this element's annotation for the specified type, or
709    *         <code>null</code> if no such annotation exists.
710    * @throws NullPointerException if the annotation class is <code>null</code>.
711    */
getAnnotation(Class<T> annotationClass)712   public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
713   {
714     // Inescapable as the VM layer is 1.4 based. T will erase to Annotation anyway.
715     @SuppressWarnings("unchecked") T ann = (T) f.getAnnotation(annotationClass);
716     return ann;
717   }
718 
719   /**
720    * Returns all annotations directly defined by the element.  If there are
721    * no annotations directly associated with the element, then a zero-length
722    * array will be returned.  The returned array may be modified by the client
723    * code, but this will have no effect on the annotation content of this
724    * class, and hence no effect on the return value of this method for
725    * future callers.
726    *
727    * @return the annotations directly defined by the element.
728    * @since 1.5
729    */
getDeclaredAnnotations()730   public Annotation[] getDeclaredAnnotations()
731   {
732     return f.getDeclaredAnnotations();
733   }
734 
735 }
736