jdk/src/share/classes/java/lang/Class.java
changeset 20180 0dedfb3744f2
parent 19834 c43d94c72c41
child 20851 9f284cf7836b
child 20481 2735b307d256
equal deleted inserted replaced
20179:fa41a3d5805e 20180:0dedfb3744f2
    46 import java.security.PrivilegedAction;
    46 import java.security.PrivilegedAction;
    47 import java.util.ArrayList;
    47 import java.util.ArrayList;
    48 import java.util.Arrays;
    48 import java.util.Arrays;
    49 import java.util.Collection;
    49 import java.util.Collection;
    50 import java.util.HashSet;
    50 import java.util.HashSet;
       
    51 import java.util.LinkedHashMap;
    51 import java.util.List;
    52 import java.util.List;
    52 import java.util.Set;
    53 import java.util.Set;
    53 import java.util.Map;
    54 import java.util.Map;
    54 import java.util.HashMap;
    55 import java.util.HashMap;
    55 import java.util.Objects;
    56 import java.util.Objects;
  2368         private static final Unsafe unsafe = Unsafe.getUnsafe();
  2369         private static final Unsafe unsafe = Unsafe.getUnsafe();
  2369         // offset of Class.reflectionData instance field
  2370         // offset of Class.reflectionData instance field
  2370         private static final long reflectionDataOffset;
  2371         private static final long reflectionDataOffset;
  2371         // offset of Class.annotationType instance field
  2372         // offset of Class.annotationType instance field
  2372         private static final long annotationTypeOffset;
  2373         private static final long annotationTypeOffset;
       
  2374         // offset of Class.annotationData instance field
       
  2375         private static final long annotationDataOffset;
  2373 
  2376 
  2374         static {
  2377         static {
  2375             Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches
  2378             Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches
  2376             reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
  2379             reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
  2377             annotationTypeOffset = objectFieldOffset(fields, "annotationType");
  2380             annotationTypeOffset = objectFieldOffset(fields, "annotationType");
       
  2381             annotationDataOffset = objectFieldOffset(fields, "annotationData");
  2378         }
  2382         }
  2379 
  2383 
  2380         private static long objectFieldOffset(Field[] fields, String fieldName) {
  2384         private static long objectFieldOffset(Field[] fields, String fieldName) {
  2381             Field field = searchFields(fields, fieldName);
  2385             Field field = searchFields(fields, fieldName);
  2382             if (field == null) {
  2386             if (field == null) {
  2394         static <T> boolean casAnnotationType(Class<?> clazz,
  2398         static <T> boolean casAnnotationType(Class<?> clazz,
  2395                                              AnnotationType oldType,
  2399                                              AnnotationType oldType,
  2396                                              AnnotationType newType) {
  2400                                              AnnotationType newType) {
  2397             return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
  2401             return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
  2398         }
  2402         }
       
  2403 
       
  2404         static <T> boolean casAnnotationData(Class<?> clazz,
       
  2405                                              AnnotationData oldData,
       
  2406                                              AnnotationData newData) {
       
  2407             return unsafe.compareAndSwapObject(clazz, annotationDataOffset, oldData, newData);
       
  2408         }
  2399     }
  2409     }
  2400 
  2410 
  2401     /**
  2411     /**
  2402      * Reflection support.
  2412      * Reflection support.
  2403      */
  2413      */
  2404 
  2414 
  2405     // Caches for certain reflective results
  2415     // Caches for certain reflective results
  2406     private static boolean useCaches = true;
  2416     private static boolean useCaches = true;
  2407 
  2417 
  2408     // reflection data that might get invalidated when JVM TI RedefineClasses() is called
  2418     // reflection data that might get invalidated when JVM TI RedefineClasses() is called
  2409     static class ReflectionData<T> {
  2419     private static class ReflectionData<T> {
  2410         volatile Field[] declaredFields;
  2420         volatile Field[] declaredFields;
  2411         volatile Field[] publicFields;
  2421         volatile Field[] publicFields;
  2412         volatile Method[] declaredMethods;
  2422         volatile Method[] declaredMethods;
  2413         volatile Method[] publicMethods;
  2423         volatile Method[] publicMethods;
  2414         volatile Constructor<T>[] declaredConstructors;
  2424         volatile Constructor<T>[] declaredConstructors;
  3251      */
  3261      */
  3252     @SuppressWarnings("unchecked")
  3262     @SuppressWarnings("unchecked")
  3253     public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
  3263     public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
  3254         Objects.requireNonNull(annotationClass);
  3264         Objects.requireNonNull(annotationClass);
  3255 
  3265 
  3256         initAnnotationsIfNecessary();
  3266         return (A) annotationData().annotations.get(annotationClass);
  3257         return (A) annotations.get(annotationClass);
       
  3258     }
  3267     }
  3259 
  3268 
  3260     /**
  3269     /**
  3261      * {@inheritDoc}
  3270      * {@inheritDoc}
  3262      * @throws NullPointerException {@inheritDoc}
  3271      * @throws NullPointerException {@inheritDoc}
  3273      */
  3282      */
  3274     @Override
  3283     @Override
  3275     public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
  3284     public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
  3276         Objects.requireNonNull(annotationClass);
  3285         Objects.requireNonNull(annotationClass);
  3277 
  3286 
  3278         initAnnotationsIfNecessary();
  3287         return AnnotationSupport.getMultipleAnnotations(annotationData().annotations, annotationClass);
  3279         return AnnotationSupport.getMultipleAnnotations(annotations, annotationClass);
       
  3280     }
  3288     }
  3281 
  3289 
  3282     /**
  3290     /**
  3283      * @since 1.5
  3291      * @since 1.5
  3284      */
  3292      */
  3285     public Annotation[] getAnnotations() {
  3293     public Annotation[] getAnnotations() {
  3286         initAnnotationsIfNecessary();
  3294         return AnnotationParser.toArray(annotationData().annotations);
  3287         return AnnotationParser.toArray(annotations);
       
  3288     }
  3295     }
  3289 
  3296 
  3290     /**
  3297     /**
  3291      * @throws NullPointerException {@inheritDoc}
  3298      * @throws NullPointerException {@inheritDoc}
  3292      * @since 1.8
  3299      * @since 1.8
  3294     @Override
  3301     @Override
  3295     @SuppressWarnings("unchecked")
  3302     @SuppressWarnings("unchecked")
  3296     public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
  3303     public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
  3297         Objects.requireNonNull(annotationClass);
  3304         Objects.requireNonNull(annotationClass);
  3298 
  3305 
  3299         initAnnotationsIfNecessary();
  3306         return (A) annotationData().declaredAnnotations.get(annotationClass);
  3300         return (A) declaredAnnotations.get(annotationClass);
       
  3301     }
  3307     }
  3302 
  3308 
  3303     /**
  3309     /**
  3304      * @throws NullPointerException {@inheritDoc}
  3310      * @throws NullPointerException {@inheritDoc}
  3305      * @since 1.8
  3311      * @since 1.8
  3306      */
  3312      */
  3307     @Override
  3313     @Override
  3308     public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
  3314     public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
  3309         Objects.requireNonNull(annotationClass);
  3315         Objects.requireNonNull(annotationClass);
  3310 
  3316 
  3311         initAnnotationsIfNecessary();
  3317         return AnnotationSupport.getMultipleAnnotations(annotationData().declaredAnnotations, annotationClass);
  3312         return AnnotationSupport.getMultipleAnnotations(declaredAnnotations, annotationClass);
       
  3313     }
  3318     }
  3314 
  3319 
  3315     /**
  3320     /**
  3316      * @since 1.5
  3321      * @since 1.5
  3317      */
  3322      */
  3318     public Annotation[] getDeclaredAnnotations()  {
  3323     public Annotation[] getDeclaredAnnotations()  {
  3319         initAnnotationsIfNecessary();
  3324         return AnnotationParser.toArray(annotationData().declaredAnnotations);
  3320         return AnnotationParser.toArray(declaredAnnotations);
  3325     }
       
  3326 
       
  3327     // annotation data that might get invalidated when JVM TI RedefineClasses() is called
       
  3328     private static class AnnotationData {
       
  3329         final Map<Class<? extends Annotation>, Annotation> annotations;
       
  3330         final Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
       
  3331 
       
  3332         // Value of classRedefinedCount when we created this AnnotationData instance
       
  3333         final int redefinedCount;
       
  3334 
       
  3335         AnnotationData(Map<Class<? extends Annotation>, Annotation> annotations,
       
  3336                        Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
       
  3337                        int redefinedCount) {
       
  3338             this.annotations = annotations;
       
  3339             this.declaredAnnotations = declaredAnnotations;
       
  3340             this.redefinedCount = redefinedCount;
       
  3341         }
  3321     }
  3342     }
  3322 
  3343 
  3323     // Annotations cache
  3344     // Annotations cache
  3324     private transient Map<Class<? extends Annotation>, Annotation> annotations;
  3345     @SuppressWarnings("UnusedDeclaration")
  3325     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
  3346     private volatile transient AnnotationData annotationData;
  3326     // Value of classRedefinedCount when we last cleared the cached annotations and declaredAnnotations fields
  3347 
  3327     private  transient int lastAnnotationsRedefinedCount = 0;
  3348     private AnnotationData annotationData() {
  3328 
  3349         while (true) { // retry loop
  3329     // Clears cached values that might possibly have been obsoleted by
  3350             AnnotationData annotationData = this.annotationData;
  3330     // a class redefinition.
  3351             int classRedefinedCount = this.classRedefinedCount;
  3331     private void clearAnnotationCachesOnClassRedefinition() {
  3352             if (annotationData != null &&
  3332         if (lastAnnotationsRedefinedCount != classRedefinedCount) {
  3353                 annotationData.redefinedCount == classRedefinedCount) {
  3333             annotations = declaredAnnotations = null;
  3354                 return annotationData;
  3334             lastAnnotationsRedefinedCount = classRedefinedCount;
  3355             }
  3335         }
  3356             // null or stale annotationData -> optimistically create new instance
  3336     }
  3357             AnnotationData newAnnotationData = createAnnotationData(classRedefinedCount);
  3337 
  3358             // try to install it
  3338     private synchronized void initAnnotationsIfNecessary() {
  3359             if (Atomic.casAnnotationData(this, annotationData, newAnnotationData)) {
  3339         clearAnnotationCachesOnClassRedefinition();
  3360                 // successfully installed new AnnotationData
  3340         if (annotations != null)
  3361                 return newAnnotationData;
  3341             return;
  3362             }
  3342         declaredAnnotations = AnnotationParser.parseAnnotations(
  3363         }
  3343             getRawAnnotations(), getConstantPool(), this);
  3364     }
       
  3365 
       
  3366     private AnnotationData createAnnotationData(int classRedefinedCount) {
       
  3367         Map<Class<? extends Annotation>, Annotation> declaredAnnotations =
       
  3368             AnnotationParser.parseAnnotations(getRawAnnotations(), getConstantPool(), this);
  3344         Class<?> superClass = getSuperclass();
  3369         Class<?> superClass = getSuperclass();
  3345         if (superClass == null) {
  3370         Map<Class<? extends Annotation>, Annotation> annotations = null;
       
  3371         if (superClass != null) {
       
  3372             Map<Class<? extends Annotation>, Annotation> superAnnotations =
       
  3373                 superClass.annotationData().annotations;
       
  3374             for (Map.Entry<Class<? extends Annotation>, Annotation> e : superAnnotations.entrySet()) {
       
  3375                 Class<? extends Annotation> annotationClass = e.getKey();
       
  3376                 if (AnnotationType.getInstance(annotationClass).isInherited()) {
       
  3377                     if (annotations == null) { // lazy construction
       
  3378                         annotations = new LinkedHashMap<>((Math.max(
       
  3379                                 declaredAnnotations.size(),
       
  3380                                 Math.min(12, declaredAnnotations.size() + superAnnotations.size())
       
  3381                             ) * 4 + 2) / 3
       
  3382                         );
       
  3383                     }
       
  3384                     annotations.put(annotationClass, e.getValue());
       
  3385                 }
       
  3386             }
       
  3387         }
       
  3388         if (annotations == null) {
       
  3389             // no inherited annotations -> share the Map with declaredAnnotations
  3346             annotations = declaredAnnotations;
  3390             annotations = declaredAnnotations;
  3347         } else {
  3391         } else {
  3348             annotations = new HashMap<>();
  3392             // at least one inherited annotation -> declared may override inherited
  3349             superClass.initAnnotationsIfNecessary();
       
  3350             for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
       
  3351                 Class<? extends Annotation> annotationClass = e.getKey();
       
  3352                 if (AnnotationType.getInstance(annotationClass).isInherited())
       
  3353                     annotations.put(annotationClass, e.getValue());
       
  3354             }
       
  3355             annotations.putAll(declaredAnnotations);
  3393             annotations.putAll(declaredAnnotations);
  3356         }
  3394         }
       
  3395         return new AnnotationData(annotations, declaredAnnotations, classRedefinedCount);
  3357     }
  3396     }
  3358 
  3397 
  3359     // Annotation types cache their internal (AnnotationType) form
  3398     // Annotation types cache their internal (AnnotationType) form
  3360 
  3399 
  3361     @SuppressWarnings("UnusedDeclaration")
  3400     @SuppressWarnings("UnusedDeclaration")