src/share/classes/java/lang/reflect/Field.java

Print this page




  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() {


 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     /**
1022      * @since 1.5
1023      */
1024     public Annotation[] getDeclaredAnnotations()  {
1025         return AnnotationParser.toArray(declaredAnnotations());
1026     }
1027 
1028     private transient Map<Class, Annotation> declaredAnnotations;
1029 
1030     private synchronized  Map<Class, Annotation> declaredAnnotations() {
1031         if (declaredAnnotations == null) {
1032             declaredAnnotations = AnnotationParser.parseAnnotations(
1033                 annotations, sun.misc.SharedSecrets.getJavaLangAccess().
1034                 getConstantPool(getDeclaringClass()),
1035                 getDeclaringClass());
1036         }
1037         return declaredAnnotations;
1038     }
1039 }


  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() {


 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     /**
1022      * @since 1.5
1023      */
1024     public Annotation[] getDeclaredAnnotations()  {
1025         return AnnotationParser.toArray(declaredAnnotations());
1026     }
1027 
1028     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
1029 
1030     private synchronized  Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
1031         if (declaredAnnotations == null) {
1032             declaredAnnotations = AnnotationParser.parseAnnotations(
1033                 annotations, sun.misc.SharedSecrets.getJavaLangAccess().
1034                 getConstantPool(getDeclaringClass()),
1035                 getDeclaringClass());
1036         }
1037         return declaredAnnotations;
1038     }
1039 }