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

Save This Page
Home » openjdk-7 » java » lang » reflect » [javadoc | source]