• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.lang.reflect;
28 
29 import sun.reflect.CallerSensitive;
30 import sun.reflect.Reflection;
31 import java.lang.annotation.Annotation;
32 import java.util.Map;
33 import com.android.dex.Dex;
34 import libcore.reflect.GenericSignatureParser;
35 import java.util.List;
36 
37 
38 /**
39  * A {@code Field} provides information about, and dynamic access to, a
40  * single field of a class or an interface.  The reflected field may
41  * be a class (static) field or an instance field.
42  *
43  * <p>A {@code Field} permits widening conversions to occur during a get or
44  * set access operation, but throws an {@code IllegalArgumentException} if a
45  * narrowing conversion would occur.
46  *
47  * @see Member
48  * @see java.lang.Class
49  * @see java.lang.Class#getFields()
50  * @see java.lang.Class#getField(String)
51  * @see java.lang.Class#getDeclaredFields()
52  * @see java.lang.Class#getDeclaredField(String)
53  *
54  * @author Kenneth Russell
55  * @author Nakul Saraiya
56  */
57 public final
58 class Field extends AccessibleObject implements Member {
59 
60     private int accessFlags;
61     private Class<?> declaringClass;
62     private int dexFieldIndex;
63     private int offset;
64     private Class<?> type;
65 
Field()66     private Field() {
67     }
68 
69     /**
70      * Returns the {@code Class} object representing the class or interface
71      * that declares the field represented by this {@code Field} object.
72      */
getDeclaringClass()73     public Class<?> getDeclaringClass() {
74         return declaringClass;
75     }
76 
77     /**
78      * Returns the name of the field represented by this {@code Field} object.
79      */
getName()80     public String getName() {
81         if (dexFieldIndex == -1) {
82             // Proxy classes have 1 synthesized static field with no valid dex index.
83             if (!declaringClass.isProxy()) {
84                 throw new AssertionError();
85             }
86             return "throws";
87         }
88         Dex dex = declaringClass.getDex();
89         int nameIndex = dex.nameIndexFromFieldIndex(dexFieldIndex);
90         return declaringClass.getDexCacheString(dex, nameIndex);
91     }
92 
93     /**
94      * Returns the Java language modifiers for the field represented
95      * by this {@code Field} object, as an integer. The {@code Modifier} class should
96      * be used to decode the modifiers.
97      *
98      * @see Modifier
99      */
getModifiers()100     public int getModifiers() {
101         return accessFlags & 0xffff;  // mask out bits not used by Java
102     }
103 
104     /**
105      * Returns {@code true} if this field represents an element of
106      * an enumerated type; returns {@code false} otherwise.
107      *
108      * @return {@code true} if and only if this field represents an element of
109      * an enumerated type.
110      * @since 1.5
111      */
isEnumConstant()112     public boolean isEnumConstant() {
113         return (getModifiers() & Modifier.ENUM) != 0;
114     }
115 
116     /**
117      * Returns {@code true} if this field is a synthetic
118      * field; returns {@code false} otherwise.
119      *
120      * @return true if and only if this field is a synthetic
121      * field as defined by the Java Language Specification.
122      * @since 1.5
123      */
isSynthetic()124     public boolean isSynthetic() {
125         return Modifier.isSynthetic(getModifiers());
126     }
127 
128     /**
129      * Returns a {@code Class} object that identifies the
130      * declared type for the field represented by this
131      * {@code Field} object.
132      *
133      * @return a {@code Class} object identifying the declared
134      * type of the field represented by this object
135      */
getType()136     public Class<?> getType() {
137         return type;
138     }
139 
140     /**
141      * Returns a {@code Type} object that represents the declared type for
142      * the field represented by this {@code Field} object.
143      *
144      * <p>If the {@code Type} is a parameterized type, the
145      * {@code Type} object returned must accurately reflect the
146      * actual type parameters used in the source code.
147      *
148      * <p>If the type of the underlying field is a type variable or a
149      * parameterized type, it is created. Otherwise, it is resolved.
150      *
151      * @return a {@code Type} object that represents the declared type for
152      *     the field represented by this {@code Field} object
153      * @throws GenericSignatureFormatError if the generic field
154      *     signature does not conform to the format specified in
155      *     <cite>The Java&trade; Virtual Machine Specification</cite>
156      * @throws TypeNotPresentException if the generic type
157      *     signature of the underlying field refers to a non-existent
158      *     type declaration
159      * @throws MalformedParameterizedTypeException if the generic
160      *     signature of the underlying field refers to a parameterized type
161      *     that cannot be instantiated for any reason
162      * @since 1.5
163      */
getGenericType()164     public Type getGenericType() {
165         String signatureAttribute = getSignatureAttribute();
166         ClassLoader cl = declaringClass.getClassLoader();
167         GenericSignatureParser parser = new GenericSignatureParser(cl);
168         parser.parseForField(declaringClass, signatureAttribute);
169         Type genericType = parser.fieldType;
170         if (genericType == null) {
171             genericType = getType();
172         }
173         return genericType;
174     }
175 
getSignatureAttribute()176     private String getSignatureAttribute() {
177         String[] annotation = getSignatureAnnotation();
178         if (annotation == null) {
179             return null;
180         }
181         StringBuilder result = new StringBuilder();
182         for (String s : annotation) {
183             result.append(s);
184         }
185         return result.toString();
186     }
getSignatureAnnotation()187     private native String[] getSignatureAnnotation();
188 
189 
190     /**
191      * Compares this {@code Field} against the specified object.  Returns
192      * true if the objects are the same.  Two {@code Field} objects are the same if
193      * they were declared by the same class and have the same name
194      * and type.
195      */
equals(Object obj)196     public boolean equals(Object obj) {
197         if (obj != null && obj instanceof Field) {
198             Field other = (Field)obj;
199             return (getDeclaringClass() == other.getDeclaringClass())
200                 && (getName() == other.getName())
201                 && (getType() == other.getType());
202         }
203         return false;
204     }
205 
206     /**
207      * Returns a hashcode for this {@code Field}.  This is computed as the
208      * exclusive-or of the hashcodes for the underlying field's
209      * declaring class name and its name.
210      */
hashCode()211     public int hashCode() {
212         return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
213     }
214 
215     /**
216      * Returns a string describing this {@code Field}.  The format is
217      * the access modifiers for the field, if any, followed
218      * by the field type, followed by a space, followed by
219      * the fully-qualified name of the class declaring the field,
220      * followed by a period, followed by the name of the field.
221      * For example:
222      * <pre>
223      *    public static final int java.lang.Thread.MIN_PRIORITY
224      *    private int java.io.FileDescriptor.fd
225      * </pre>
226      *
227      * <p>The modifiers are placed in canonical order as specified by
228      * "The Java Language Specification".  This is {@code public},
229      * {@code protected} or {@code private} first, and then other
230      * modifiers in the following order: {@code static}, {@code final},
231      * {@code transient}, {@code volatile}.
232      */
toString()233     public String toString() {
234         int mod = getModifiers();
235         return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
236             + getTypeName(getType()) + " "
237             + getTypeName(getDeclaringClass()) + "."
238             + getName());
239     }
240 
241     /**
242      * Returns a string describing this {@code Field}, including
243      * its generic type.  The format is the access modifiers for the
244      * field, if any, followed by the generic field type, followed by
245      * a space, followed by the fully-qualified name of the class
246      * declaring the field, followed by a period, followed by the name
247      * of the field.
248      *
249      * <p>The modifiers are placed in canonical order as specified by
250      * "The Java Language Specification".  This is {@code public},
251      * {@code protected} or {@code private} first, and then other
252      * modifiers in the following order: {@code static}, {@code final},
253      * {@code transient}, {@code volatile}.
254      *
255      * @return a string describing this {@code Field}, including
256      * its generic type
257      *
258      * @since 1.5
259      */
toGenericString()260     public String toGenericString() {
261         int mod = getModifiers();
262         Type fieldType = getGenericType();
263         return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
264             +  ((fieldType instanceof Class) ?
265                 getTypeName((Class)fieldType): fieldType.toString())+ " "
266             + getTypeName(getDeclaringClass()) + "."
267             + getName());
268     }
269 
270     /**
271      * Returns the value of the field represented by this {@code Field}, on
272      * the specified object. The value is automatically wrapped in an
273      * object if it has a primitive type.
274      *
275      * <p>The underlying field's value is obtained as follows:
276      *
277      * <p>If the underlying field is a static field, the {@code obj} argument
278      * is ignored; it may be null.
279      *
280      * <p>Otherwise, the underlying field is an instance field.  If the
281      * specified {@code obj} argument is null, the method throws a
282      * {@code NullPointerException}. If the specified object is not an
283      * instance of the class or interface declaring the underlying
284      * field, the method throws an {@code IllegalArgumentException}.
285      *
286      * <p>If this {@code Field} object is enforcing Java language access control, and
287      * the underlying field is inaccessible, the method throws an
288      * {@code IllegalAccessException}.
289      * If the underlying field is static, the class that declared the
290      * field is initialized if it has not already been initialized.
291      *
292      * <p>Otherwise, the value is retrieved from the underlying instance
293      * or static field.  If the field has a primitive type, the value
294      * is wrapped in an object before being returned, otherwise it is
295      * returned as is.
296      *
297      * <p>If the field is hidden in the type of {@code obj},
298      * the field's value is obtained according to the preceding rules.
299      *
300      * @param object object from which the represented field's value is
301      * to be extracted
302      * @return the value of the represented field in object
303      * {@code obj}; primitive values are wrapped in an appropriate
304      * object before being returned
305      *
306      * @exception IllegalAccessException    if this {@code Field} object
307      *              is enforcing Java language access control and the underlying
308      *              field is inaccessible.
309      * @exception IllegalArgumentException  if the specified object is not an
310      *              instance of the class or interface declaring the underlying
311      *              field (or a subclass or implementor thereof).
312      * @exception NullPointerException      if the specified object is null
313      *              and the field is an instance field.
314      * @exception ExceptionInInitializerError if the initialization provoked
315      *              by this method fails.
316      */
get(Object object)317     public native Object get(Object object)
318             throws IllegalAccessException, IllegalArgumentException;
319 
320     /**
321      * Gets the value of a static or instance {@code boolean} field.
322      *
323      * @param object the object to extract the {@code boolean} value
324      * from
325      * @return the value of the {@code boolean} field
326      *
327      * @exception IllegalAccessException    if this {@code Field} object
328      *              is enforcing Java language access control and the underlying
329      *              field is inaccessible.
330      * @exception IllegalArgumentException  if the specified object is not
331      *              an instance of the class or interface declaring the
332      *              underlying field (or a subclass or implementor
333      *              thereof), or if the field value cannot be
334      *              converted to the type {@code boolean} by a
335      *              widening conversion.
336      * @exception NullPointerException      if the specified object is null
337      *              and the field is an instance field.
338      * @exception ExceptionInInitializerError if the initialization provoked
339      *              by this method fails.
340      * @see       Field#get
341      */
getBoolean(Object object)342     public native boolean getBoolean(Object object)
343             throws IllegalAccessException, IllegalArgumentException;
344 
345     /**
346      * Gets the value of a static or instance {@code byte} field.
347      *
348      * @param object the object to extract the {@code byte} value
349      * from
350      * @return the value of the {@code byte} field
351      *
352      * @exception IllegalAccessException    if this {@code Field} object
353      *              is enforcing Java language access control and the underlying
354      *              field is inaccessible.
355      * @exception IllegalArgumentException  if the specified object is not
356      *              an instance of the class or interface declaring the
357      *              underlying field (or a subclass or implementor
358      *              thereof), or if the field value cannot be
359      *              converted to the type {@code byte} by a
360      *              widening conversion.
361      * @exception NullPointerException      if the specified object is null
362      *              and the field is an instance field.
363      * @exception ExceptionInInitializerError if the initialization provoked
364      *              by this method fails.
365      * @see       Field#get
366      */
getByte(Object object)367     public native byte getByte(Object object)
368             throws IllegalAccessException, IllegalArgumentException;
369 
370     /**
371      * Gets the value of a static or instance field of type
372      * {@code char} or of another primitive type convertible to
373      * type {@code char} via a widening conversion.
374      *
375      * @param object the object to extract the {@code char} value
376      * from
377      * @return the value of the field converted to type {@code char}
378      *
379      * @exception IllegalAccessException    if this {@code Field} object
380      *              is enforcing Java language access control and the underlying
381      *              field is inaccessible.
382      * @exception IllegalArgumentException  if the specified object is not
383      *              an instance of the class or interface declaring the
384      *              underlying field (or a subclass or implementor
385      *              thereof), or if the field value cannot be
386      *              converted to the type {@code char} by a
387      *              widening conversion.
388      * @exception NullPointerException      if the specified object is null
389      *              and the field is an instance field.
390      * @exception ExceptionInInitializerError if the initialization provoked
391      *              by this method fails.
392      * @see Field#get
393      */
getChar(Object object)394     public native char getChar(Object object)
395             throws IllegalAccessException, IllegalArgumentException;
396 
397     /**
398      * Gets the value of a static or instance field of type
399      * {@code short} or of another primitive type convertible to
400      * type {@code short} via a widening conversion.
401      *
402      * @param object the object to extract the {@code short} value
403      * from
404      * @return the value of the field converted to type {@code short}
405      *
406      * @exception IllegalAccessException    if this {@code Field} object
407      *              is enforcing Java language access control and the underlying
408      *              field is inaccessible.
409      * @exception IllegalArgumentException  if the specified object is not
410      *              an instance of the class or interface declaring the
411      *              underlying field (or a subclass or implementor
412      *              thereof), or if the field value cannot be
413      *              converted to the type {@code short} by a
414      *              widening conversion.
415      * @exception NullPointerException      if the specified object is null
416      *              and the field is an instance field.
417      * @exception ExceptionInInitializerError if the initialization provoked
418      *              by this method fails.
419      * @see       Field#get
420      */
getShort(Object object)421     public native short getShort(Object object)
422             throws IllegalAccessException, IllegalArgumentException;
423 
424     /**
425      * Gets the value of a static or instance field of type
426      * {@code int} or of another primitive type convertible to
427      * type {@code int} via a widening conversion.
428      *
429      * @param object the object to extract the {@code int} value
430      * from
431      * @return the value of the field converted to type {@code int}
432      *
433      * @exception IllegalAccessException    if this {@code Field} object
434      *              is enforcing Java language access control and the underlying
435      *              field is inaccessible.
436      * @exception IllegalArgumentException  if the specified object is not
437      *              an instance of the class or interface declaring the
438      *              underlying field (or a subclass or implementor
439      *              thereof), or if the field value cannot be
440      *              converted to the type {@code int} by a
441      *              widening conversion.
442      * @exception NullPointerException      if the specified object is null
443      *              and the field is an instance field.
444      * @exception ExceptionInInitializerError if the initialization provoked
445      *              by this method fails.
446      * @see       Field#get
447      */
getInt(Object object)448     public native int getInt(Object object)
449             throws IllegalAccessException, IllegalArgumentException;
450 
451     /**
452      * Gets the value of a static or instance field of type
453      * {@code long} or of another primitive type convertible to
454      * type {@code long} via a widening conversion.
455      *
456      * @param object the object to extract the {@code long} value
457      * from
458      * @return the value of the field converted to type {@code long}
459      *
460      * @exception IllegalAccessException    if this {@code Field} object
461      *              is enforcing Java language access control and the underlying
462      *              field is inaccessible.
463      * @exception IllegalArgumentException  if the specified object is not
464      *              an instance of the class or interface declaring the
465      *              underlying field (or a subclass or implementor
466      *              thereof), or if the field value cannot be
467      *              converted to the type {@code long} by a
468      *              widening conversion.
469      * @exception NullPointerException      if the specified object is null
470      *              and the field is an instance field.
471      * @exception ExceptionInInitializerError if the initialization provoked
472      *              by this method fails.
473      * @see       Field#get
474      */
getLong(Object object)475     public native long getLong(Object object)
476             throws IllegalAccessException, IllegalArgumentException;
477 
478     /**
479      * Gets the value of a static or instance field of type
480      * {@code float} or of another primitive type convertible to
481      * type {@code float} via a widening conversion.
482      *
483      * @param object the object to extract the {@code float} value
484      * from
485      * @return the value of the field converted to type {@code float}
486      *
487      * @exception IllegalAccessException    if this {@code Field} object
488      *              is enforcing Java language access control and the underlying
489      *              field is inaccessible.
490      * @exception IllegalArgumentException  if the specified object is not
491      *              an instance of the class or interface declaring the
492      *              underlying field (or a subclass or implementor
493      *              thereof), or if the field value cannot be
494      *              converted to the type {@code float} by a
495      *              widening conversion.
496      * @exception NullPointerException      if the specified object is null
497      *              and the field is an instance field.
498      * @exception ExceptionInInitializerError if the initialization provoked
499      *              by this method fails.
500      * @see Field#get
501      */
getFloat(Object object)502     public native float getFloat(Object object)
503             throws IllegalAccessException, IllegalArgumentException;
504 
505     /**
506      * Gets the value of a static or instance field of type
507      * {@code double} or of another primitive type convertible to
508      * type {@code double} via a widening conversion.
509      *
510      * @param object the object to extract the {@code double} value
511      * from
512      * @return the value of the field converted to type {@code double}
513      *
514      * @exception IllegalAccessException    if this {@code Field} object
515      *              is enforcing Java language access control and the underlying
516      *              field is inaccessible.
517      * @exception IllegalArgumentException  if the specified object is not
518      *              an instance of the class or interface declaring the
519      *              underlying field (or a subclass or implementor
520      *              thereof), or if the field value cannot be
521      *              converted to the type {@code double} by a
522      *              widening conversion.
523      * @exception NullPointerException      if the specified object is null
524      *              and the field is an instance field.
525      * @exception ExceptionInInitializerError if the initialization provoked
526      *              by this method fails.
527      * @see       Field#get
528      */
getDouble(Object object)529     public native double getDouble(Object object)
530             throws IllegalAccessException, IllegalArgumentException;
531 
532     /**
533      * Sets the field represented by this {@code Field} object on the
534      * specified object argument to the specified new value. The new
535      * value is automatically unwrapped if the underlying field has a
536      * primitive type.
537      *
538      * <p>The operation proceeds as follows:
539      *
540      * <p>If the underlying field is static, the {@code obj} argument is
541      * ignored; it may be null.
542      *
543      * <p>Otherwise the underlying field is an instance field.  If the
544      * specified object argument is null, the method throws a
545      * {@code NullPointerException}.  If the specified object argument is not
546      * an instance of the class or interface declaring the underlying
547      * field, the method throws an {@code IllegalArgumentException}.
548      *
549      * <p>If this {@code Field} object is enforcing Java language access control, and
550      * the underlying field is inaccessible, the method throws an
551      * {@code IllegalAccessException}.
552      *
553      * <p>If the underlying field is final, the method throws an
554      * {@code IllegalAccessException} unless {@code setAccessible(true)}
555      * has succeeded for this {@code Field} object
556      * and the field is non-static. Setting a final field in this way
557      * is meaningful only during deserialization or reconstruction of
558      * instances of classes with blank final fields, before they are
559      * made available for access by other parts of a program. Use in
560      * any other context may have unpredictable effects, including cases
561      * in which other parts of a program continue to use the original
562      * value of this field.
563      *
564      * <p>If the underlying field is of a primitive type, an unwrapping
565      * conversion is attempted to convert the new value to a value of
566      * a primitive type.  If this attempt fails, the method throws an
567      * {@code IllegalArgumentException}.
568      *
569      * <p>If, after possible unwrapping, the new value cannot be
570      * converted to the type of the underlying field by an identity or
571      * widening conversion, the method throws an
572      * {@code IllegalArgumentException}.
573      *
574      * <p>If the underlying field is static, the class that declared the
575      * field is initialized if it has not already been initialized.
576      *
577      * <p>The field is set to the possibly unwrapped and widened new value.
578      *
579      * <p>If the field is hidden in the type of {@code obj},
580      * the field's value is set according to the preceding rules.
581      *
582      * @param object the object whose field should be modified
583      * @param value the new value for the field of {@code obj}
584      * being modified
585      *
586      * @exception IllegalAccessException    if this {@code Field} object
587      *              is enforcing Java language access control and the underlying
588      *              field is either inaccessible or final.
589      * @exception IllegalArgumentException  if the specified object is not an
590      *              instance of the class or interface declaring the underlying
591      *              field (or a subclass or implementor thereof),
592      *              or if an unwrapping conversion fails.
593      * @exception NullPointerException      if the specified object is null
594      *              and the field is an instance field.
595      * @exception ExceptionInInitializerError if the initialization provoked
596      *              by this method fails.
597      */
set(Object object, Object value)598     public native void set(Object object, Object value)
599             throws IllegalAccessException, IllegalArgumentException;
600 
601     /**
602      * Sets the value of a field as a {@code boolean} on the specified object.
603      * This method is equivalent to
604      * {@code set(obj, zObj)},
605      * where {@code zObj} is a {@code Boolean} object and
606      * {@code zObj.booleanValue() == z}.
607      *
608      * @param object the object whose field should be modified
609      * @param value   the new value for the field of {@code obj}
610      * being modified
611      *
612      * @exception IllegalAccessException    if this {@code Field} object
613      *              is enforcing Java language access control and the underlying
614      *              field is either inaccessible or final.
615      * @exception IllegalArgumentException  if the specified object is not an
616      *              instance of the class or interface declaring the underlying
617      *              field (or a subclass or implementor thereof),
618      *              or if an unwrapping conversion fails.
619      * @exception NullPointerException      if the specified object is null
620      *              and the field is an instance field.
621      * @exception ExceptionInInitializerError if the initialization provoked
622      *              by this method fails.
623      * @see       Field#set
624      */
setBoolean(Object object, boolean value)625     public native void setBoolean(Object object, boolean value)
626             throws IllegalAccessException, IllegalArgumentException;
627 
628     /**
629      * Sets the value of a field as a {@code byte} on the specified object.
630      * This method is equivalent to
631      * {@code set(obj, bObj)},
632      * where {@code bObj} is a {@code Byte} object and
633      * {@code bObj.byteValue() == b}.
634      *
635      * @param object the object whose field should be modified
636      * @param value   the new value for the field of {@code obj}
637      * being modified
638      *
639      * @exception IllegalAccessException    if this {@code Field} object
640      *              is enforcing Java language access control and the underlying
641      *              field is either inaccessible or final.
642      * @exception IllegalArgumentException  if the specified object is not an
643      *              instance of the class or interface declaring the underlying
644      *              field (or a subclass or implementor thereof),
645      *              or if an unwrapping conversion fails.
646      * @exception NullPointerException      if the specified object is null
647      *              and the field is an instance field.
648      * @exception ExceptionInInitializerError if the initialization provoked
649      *              by this method fails.
650      * @see       Field#set
651      */
setByte(Object object, byte value)652     public native void setByte(Object object, byte value)
653             throws IllegalAccessException, IllegalArgumentException;
654 
655     /**
656      * Sets the value of a field as a {@code char} on the specified object.
657      * This method is equivalent to
658      * {@code set(obj, cObj)},
659      * where {@code cObj} is a {@code Character} object and
660      * {@code cObj.charValue() == c}.
661      *
662      * @param object the object whose field should be modified
663      * @param value   the new value for the field of {@code obj}
664      * being modified
665      *
666      * @exception IllegalAccessException    if this {@code Field} object
667      *              is enforcing Java language access control and the underlying
668      *              field is either inaccessible or final.
669      * @exception IllegalArgumentException  if the specified object is not an
670      *              instance of the class or interface declaring the underlying
671      *              field (or a subclass or implementor thereof),
672      *              or if an unwrapping conversion fails.
673      * @exception NullPointerException      if the specified object is null
674      *              and the field is an instance field.
675      * @exception ExceptionInInitializerError if the initialization provoked
676      *              by this method fails.
677      * @see       Field#set
678      */
setChar(Object object, char value)679     public native void setChar(Object object, char value)
680             throws IllegalAccessException, IllegalArgumentException;
681 
682     /**
683      * Sets the value of a field as a {@code short} on the specified object.
684      * This method is equivalent to
685      * {@code set(obj, sObj)},
686      * where {@code sObj} is a {@code Short} object and
687      * {@code sObj.shortValue() == s}.
688      *
689      * @param object the object whose field should be modified
690      * @param value   the new value for the field of {@code obj}
691      * being modified
692      *
693      * @exception IllegalAccessException    if this {@code Field} object
694      *              is enforcing Java language access control and the underlying
695      *              field is either inaccessible or final.
696      * @exception IllegalArgumentException  if the specified object is not an
697      *              instance of the class or interface declaring the underlying
698      *              field (or a subclass or implementor thereof),
699      *              or if an unwrapping conversion fails.
700      * @exception NullPointerException      if the specified object is null
701      *              and the field is an instance field.
702      * @exception ExceptionInInitializerError if the initialization provoked
703      *              by this method fails.
704      * @see       Field#set
705      */
setShort(Object object, short value)706     public native void setShort(Object object, short value)
707             throws IllegalAccessException, IllegalArgumentException;
708 
709     /**
710      * Sets the value of a field as an {@code int} on the specified object.
711      * This method is equivalent to
712      * {@code set(obj, iObj)},
713      * where {@code iObj} is a {@code Integer} object and
714      * {@code iObj.intValue() == i}.
715      *
716      * @param object the object whose field should be modified
717      * @param value   the new value for the field of {@code obj}
718      * being modified
719      *
720      * @exception IllegalAccessException    if this {@code Field} object
721      *              is enforcing Java language access control and the underlying
722      *              field is either inaccessible or final.
723      * @exception IllegalArgumentException  if the specified object is not an
724      *              instance of the class or interface declaring the underlying
725      *              field (or a subclass or implementor thereof),
726      *              or if an unwrapping conversion fails.
727      * @exception NullPointerException      if the specified object is null
728      *              and the field is an instance field.
729      * @exception ExceptionInInitializerError if the initialization provoked
730      *              by this method fails.
731      * @see       Field#set
732      */
setInt(Object object, int value)733     public native void setInt(Object object, int value)
734             throws IllegalAccessException, IllegalArgumentException;
735 
736     /**
737      * Sets the value of a field as a {@code long} on the specified object.
738      * This method is equivalent to
739      * {@code set(obj, lObj)},
740      * where {@code lObj} is a {@code Long} object and
741      * {@code lObj.longValue() == l}.
742      *
743      * @param object the object whose field should be modified
744      * @param value   the new value for the field of {@code obj}
745      * being modified
746      *
747      * @exception IllegalAccessException    if this {@code Field} object
748      *              is enforcing Java language access control and the underlying
749      *              field is either inaccessible or final.
750      * @exception IllegalArgumentException  if the specified object is not an
751      *              instance of the class or interface declaring the underlying
752      *              field (or a subclass or implementor thereof),
753      *              or if an unwrapping conversion fails.
754      * @exception NullPointerException      if the specified object is null
755      *              and the field is an instance field.
756      * @exception ExceptionInInitializerError if the initialization provoked
757      *              by this method fails.
758      * @see       Field#set
759      */
setLong(Object object, long value)760     public native void setLong(Object object, long value)
761             throws IllegalAccessException, IllegalArgumentException;
762 
763     /**
764      * Sets the value of a field as a {@code float} on the specified object.
765      * This method is equivalent to
766      * {@code set(obj, fObj)},
767      * where {@code fObj} is a {@code Float} object and
768      * {@code fObj.floatValue() == f}.
769      *
770      * @param object the object whose field should be modified
771      * @param value   the new value for the field of {@code obj}
772      * being modified
773      *
774      * @exception IllegalAccessException    if this {@code Field} object
775      *              is enforcing Java language access control and the underlying
776      *              field is either inaccessible or final.
777      * @exception IllegalArgumentException  if the specified object is not an
778      *              instance of the class or interface declaring the underlying
779      *              field (or a subclass or implementor thereof),
780      *              or if an unwrapping conversion fails.
781      * @exception NullPointerException      if the specified object is null
782      *              and the field is an instance field.
783      * @exception ExceptionInInitializerError if the initialization provoked
784      *              by this method fails.
785      * @see       Field#set
786      */
setFloat(Object object, float value)787     public native void setFloat(Object object, float value)
788             throws IllegalAccessException, IllegalArgumentException;
789 
790     /**
791      * Sets the value of a field as a {@code double} on the specified object.
792      * This method is equivalent to
793      * {@code set(obj, dObj)},
794      * where {@code dObj} is a {@code Double} object and
795      * {@code dObj.doubleValue() == d}.
796      *
797      * @param object the object whose field should be modified
798      * @param value   the new value for the field of {@code obj}
799      * being modified
800      *
801      * @exception IllegalAccessException    if this {@code Field} object
802      *              is enforcing Java language access control and the underlying
803      *              field is either inaccessible or final.
804      * @exception IllegalArgumentException  if the specified object is not an
805      *              instance of the class or interface declaring the underlying
806      *              field (or a subclass or implementor thereof),
807      *              or if an unwrapping conversion fails.
808      * @exception NullPointerException      if the specified object is null
809      *              and the field is an instance field.
810      * @exception ExceptionInInitializerError if the initialization provoked
811      *              by this method fails.
812      * @see       Field#set
813      */
setDouble(Object object, double value)814     public native void setDouble(Object object, double value)
815             throws IllegalAccessException, IllegalArgumentException;
816 
817     /*
818      * Utility routine to paper over array type names
819      */
getTypeName(Class<?> type)820     static String getTypeName(Class<?> type) {
821         if (type.isArray()) {
822             try {
823                 Class<?> cl = type;
824                 int dimensions = 0;
825                 while (cl.isArray()) {
826                     dimensions++;
827                     cl = cl.getComponentType();
828                 }
829                 StringBuffer sb = new StringBuffer();
830                 sb.append(cl.getName());
831                 for (int i = 0; i < dimensions; i++) {
832                     sb.append("[]");
833                 }
834                 return sb.toString();
835             } catch (Throwable e) { /*FALLTHRU*/ }
836         }
837         return type.getName();
838     }
839 
840     /**
841      * @throws NullPointerException {@inheritDoc}
842      * @since 1.5
843      */
getAnnotation(Class<A> annotationType)844     @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
845         if (annotationType == null) {
846             throw new NullPointerException("annotationType == null");
847         }
848         return getAnnotationNative(annotationType);
849     }
getAnnotationNative(Class<A> annotationType)850     private native <A extends Annotation> A getAnnotationNative(Class<A> annotationType);
851 
isAnnotationPresent(Class<? extends Annotation> annotationType)852     @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
853         if (annotationType == null) {
854             throw new NullPointerException("annotationType == null");
855         }
856         return isAnnotationPresentNative(annotationType);
857     }
isAnnotationPresentNative(Class<? extends Annotation> annotationType)858     private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType);
859 
860     /**
861      * @since 1.5
862      */
getDeclaredAnnotations()863     @Override public native Annotation[] getDeclaredAnnotations();
864 
865     /**
866      * Returns the index of this field's ID in its dex file.
867      *
868      * @hide
869      */
getDexFieldIndex()870     public int getDexFieldIndex() {
871         return dexFieldIndex;
872     }
873 
874     /**
875      * Returns the offset of the field within an instance, or for static fields, the class.
876      *
877      * @hide
878      */
getOffset()879     public int getOffset() {
880         return offset;
881     }
882 }
883