Home | History | Annotate | Download | only in reflect
      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 
     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      */
     73     public Class<?> getDeclaringClass() {
     74         return declaringClass;
     75     }
     76 
     77     /**
     78      * Returns the name of the field represented by this {@code Field} object.
     79      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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 
    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     }
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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     }
    850     private native <A extends Annotation> A getAnnotationNative(Class<A> annotationType);
    851 
    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     }
    858     private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType);
    859 
    860     /**
    861      * @since 1.5
    862      */
    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      */
    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      */
    879     public int getOffset() {
    880         return offset;
    881     }
    882 }
    883