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