src/share/classes/java/lang/Class.java

Print this page




2291             return name;
2292         }
2293         if (!name.startsWith("/")) {
2294             Class<?> c = this;
2295             while (c.isArray()) {
2296                 c = c.getComponentType();
2297             }
2298             String baseName = c.getName();
2299             int index = baseName.lastIndexOf('.');
2300             if (index != -1) {
2301                 name = baseName.substring(0, index).replace('.', '/')
2302                     +"/"+name;
2303             }
2304         } else {
2305             name = name.substring(1);
2306         }
2307         return name;
2308     }
2309 
2310     /**







































2311      * Reflection support.
2312      */
2313 
2314     // Caches for certain reflective results
2315     private static boolean useCaches = true;
2316 
2317     // reflection data that might get invalidated when JVM TI RedefineClasses() is called
2318     static class ReflectionData<T> {
2319         volatile Field[] declaredFields;
2320         volatile Field[] publicFields;
2321         volatile Method[] declaredMethods;
2322         volatile Method[] publicMethods;
2323         volatile Constructor<T>[] declaredConstructors;
2324         volatile Constructor<T>[] publicConstructors;
2325         // Intermediate results for getFields and getMethods
2326         volatile Field[] declaredPublicFields;
2327         volatile Method[] declaredPublicMethods;
2328         volatile Class<?>[] interfaces;
2329 
2330         // Value of classRedefinedCount when we created this ReflectionData instance
2331         final int redefinedCount;
2332 
2333         ReflectionData(int redefinedCount) {
2334             this.redefinedCount = redefinedCount;
2335         }
2336 
2337         // initialize Unsafe machinery here, since we need to call Class.class instance method
2338         // and have to avoid calling it in the static initializer of the Class class...
2339         private static final Unsafe unsafe;
2340         // offset of Class.reflectionData instance field
2341         private static final long reflectionDataOffset;
2342 
2343         static {
2344             unsafe = Unsafe.getUnsafe();
2345             // bypass caches
2346             Field reflectionDataField = searchFields(Class.class.getDeclaredFields0(false),
2347                                                      "reflectionData");
2348             if (reflectionDataField == null) {
2349                 throw new Error("No reflectionData field found in java.lang.Class");
2350             }
2351             reflectionDataOffset = unsafe.objectFieldOffset(reflectionDataField);
2352         }
2353 
2354         static <T> boolean compareAndSwap(Class<?> clazz,
2355                                           SoftReference<ReflectionData<T>> oldData,
2356                                           SoftReference<ReflectionData<T>> newData) {
2357             return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
2358         }
2359     }
2360 
2361     private volatile transient SoftReference<ReflectionData<T>> reflectionData;
2362 
2363     // Incremented by the VM on each call to JVM TI RedefineClasses()
2364     // that redefines this class or a superclass.
2365     private volatile transient int classRedefinedCount = 0;
2366 
2367     // Lazily create and cache ReflectionData
2368     private ReflectionData<T> reflectionData() {
2369         SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2370         int classRedefinedCount = this.classRedefinedCount;
2371         ReflectionData<T> rd;
2372         if (useCaches &&
2373             reflectionData != null &&
2374             (rd = reflectionData.get()) != null &&
2375             rd.redefinedCount == classRedefinedCount) {
2376             return rd;
2377         }
2378         // else no SoftReference or cleared SoftReference or stale ReflectionData
2379         // -> create and replace new instance
2380         return newReflectionData(reflectionData, classRedefinedCount);
2381     }
2382 
2383     private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
2384                                                 int classRedefinedCount) {
2385         if (!useCaches) return null;
2386 
2387         while (true) {
2388             ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2389             // try to CAS it...
2390             if (ReflectionData.compareAndSwap(this, oldReflectionData, new SoftReference<>(rd))) {
2391                 return rd;
2392             }
2393             // else retry
2394             oldReflectionData = this.reflectionData;
2395             classRedefinedCount = this.classRedefinedCount;
2396             if (oldReflectionData != null &&
2397                 (rd = oldReflectionData.get()) != null &&
2398                 rd.redefinedCount == classRedefinedCount) {
2399                 return rd;
2400             }
2401         }
2402     }
2403 
2404     // Generic signature handling
2405     private native String getGenericSignature0();
2406 
2407     // Generic info repository; lazily initialized
2408     private volatile transient ClassRepository genericInfo;
2409 
2410     // accessor for factory


2413         return CoreReflectionFactory.make(this, ClassScope.make(this));
2414     }
2415 
2416     // accessor for generic info repository;
2417     // generic info is lazily initialized
2418     private ClassRepository getGenericInfo() {
2419         ClassRepository genericInfo = this.genericInfo;
2420         if (genericInfo == null) {
2421             String signature = getGenericSignature0();
2422             if (signature == null) {
2423                 genericInfo = ClassRepository.NONE;
2424             } else {
2425                 genericInfo = ClassRepository.make(signature, getFactory());
2426             }
2427             this.genericInfo = genericInfo;
2428         }
2429         return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
2430     }
2431 
2432     // Annotations handling
2433     private native byte[] getRawAnnotations();
2434     // Since 1.8
2435     native byte[] getRawTypeAnnotations();
2436     static byte[] getExecutableTypeAnnotationBytes(Executable ex) {
2437         return getReflectionFactory().getExecutableTypeAnnotationBytes(ex);
2438     }
2439 
2440     native ConstantPool getConstantPool();
2441 
2442     //
2443     //
2444     // java.lang.reflect.Field handling
2445     //
2446     //
2447 
2448     // Returns an array of "root" fields. These Field objects must NOT
2449     // be propagated to the outside world, but must instead be copied
2450     // via ReflectionFactory.copyField.
2451     private Field[] privateGetDeclaredFields(boolean publicOnly) {
2452         checkInitted();
2453         Field[] res;


3273             return;
3274         declaredAnnotations = AnnotationParser.parseAnnotations(
3275             getRawAnnotations(), getConstantPool(), this);
3276         Class<?> superClass = getSuperclass();
3277         if (superClass == null) {
3278             annotations = declaredAnnotations;
3279         } else {
3280             annotations = new HashMap<>();
3281             superClass.initAnnotationsIfNecessary();
3282             for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3283                 Class<? extends Annotation> annotationClass = e.getKey();
3284                 if (AnnotationType.getInstance(annotationClass).isInherited())
3285                     annotations.put(annotationClass, e.getValue());
3286             }
3287             annotations.putAll(declaredAnnotations);
3288         }
3289     }
3290 
3291     // Annotation types cache their internal (AnnotationType) form
3292 
3293     private AnnotationType annotationType;

3294 
3295     void setAnnotationType(AnnotationType type) {
3296         annotationType = type;
3297     }
3298 
3299     AnnotationType getAnnotationType() {
3300         return annotationType;
3301     }
3302 
3303     /* Backing store of user-defined values pertaining to this class.
3304      * Maintained by the ClassValue class.
3305      */
3306     transient ClassValue.ClassValueMap classValueMap;
3307 
3308     /**
3309      * Returns an AnnotatedType object that represents the use of a type to specify
3310      * the superclass of the entity represented by this Class. (The <em>use</em> of type
3311      * Foo to specify the superclass in '... extends Foo' is distinct from the
3312      * <em>declaration</em> of type Foo.)
3313      *
3314      * If this Class represents a class type whose declaration does not explicitly
3315      * indicate an annotated superclass, the return value is null.
3316      *




2291             return name;
2292         }
2293         if (!name.startsWith("/")) {
2294             Class<?> c = this;
2295             while (c.isArray()) {
2296                 c = c.getComponentType();
2297             }
2298             String baseName = c.getName();
2299             int index = baseName.lastIndexOf('.');
2300             if (index != -1) {
2301                 name = baseName.substring(0, index).replace('.', '/')
2302                     +"/"+name;
2303             }
2304         } else {
2305             name = name.substring(1);
2306         }
2307         return name;
2308     }
2309 
2310     /**
2311      * Atomic operations support.
2312      */
2313     private static class Atomic {
2314         // initialize Unsafe machinery here, since we need to call Class.class instance method
2315         // and have to avoid calling it in the static initializer of the Class class...
2316         private static final Unsafe unsafe = Unsafe.getUnsafe();
2317         // offset of Class.reflectionData instance field
2318         private static final long reflectionDataOffset;
2319         // offset of Class.annotationType instance field
2320         private static final long annotationTypeOffset;
2321 
2322         static {
2323             Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches
2324             reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
2325             annotationTypeOffset = objectFieldOffset(fields, "annotationType");
2326         }
2327 
2328         private static long objectFieldOffset(Field[] fields, String fieldName) {
2329             Field field = searchFields(fields, fieldName);
2330             if (field == null) {
2331                 throw new Error("No " + fieldName + " field found in java.lang.Class");
2332             }
2333             return unsafe.objectFieldOffset(field);
2334         }
2335 
2336         static <T> boolean casReflectionData(Class<?> clazz,
2337                                              SoftReference<ReflectionData<T>> oldData,
2338                                              SoftReference<ReflectionData<T>> newData) {
2339             return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
2340         }
2341 
2342         static <T> boolean casAnnotationType(Class<?> clazz,
2343                                              AnnotationType oldType,
2344                                              AnnotationType newType) {
2345             return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
2346         }
2347     }
2348 
2349     /**
2350      * Reflection support.
2351      */
2352 
2353     // Caches for certain reflective results
2354     private static boolean useCaches = true;
2355 
2356     // reflection data that might get invalidated when JVM TI RedefineClasses() is called
2357     static class ReflectionData<T> {
2358         volatile Field[] declaredFields;
2359         volatile Field[] publicFields;
2360         volatile Method[] declaredMethods;
2361         volatile Method[] publicMethods;
2362         volatile Constructor<T>[] declaredConstructors;
2363         volatile Constructor<T>[] publicConstructors;
2364         // Intermediate results for getFields and getMethods
2365         volatile Field[] declaredPublicFields;
2366         volatile Method[] declaredPublicMethods;
2367         volatile Class<?>[] interfaces;
2368 
2369         // Value of classRedefinedCount when we created this ReflectionData instance
2370         final int redefinedCount;
2371 
2372         ReflectionData(int redefinedCount) {
2373             this.redefinedCount = redefinedCount;
2374         }























2375     }
2376 
2377     private volatile transient SoftReference<ReflectionData<T>> reflectionData;
2378 
2379     // Incremented by the VM on each call to JVM TI RedefineClasses()
2380     // that redefines this class or a superclass.
2381     private volatile transient int classRedefinedCount = 0;
2382 
2383     // Lazily create and cache ReflectionData
2384     private ReflectionData<T> reflectionData() {
2385         SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2386         int classRedefinedCount = this.classRedefinedCount;
2387         ReflectionData<T> rd;
2388         if (useCaches &&
2389             reflectionData != null &&
2390             (rd = reflectionData.get()) != null &&
2391             rd.redefinedCount == classRedefinedCount) {
2392             return rd;
2393         }
2394         // else no SoftReference or cleared SoftReference or stale ReflectionData
2395         // -> create and replace new instance
2396         return newReflectionData(reflectionData, classRedefinedCount);
2397     }
2398 
2399     private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
2400                                                 int classRedefinedCount) {
2401         if (!useCaches) return null;
2402 
2403         while (true) {
2404             ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2405             // try to CAS it...
2406             if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
2407                 return rd;
2408             }
2409             // else retry
2410             oldReflectionData = this.reflectionData;
2411             classRedefinedCount = this.classRedefinedCount;
2412             if (oldReflectionData != null &&
2413                 (rd = oldReflectionData.get()) != null &&
2414                 rd.redefinedCount == classRedefinedCount) {
2415                 return rd;
2416             }
2417         }
2418     }
2419 
2420     // Generic signature handling
2421     private native String getGenericSignature0();
2422 
2423     // Generic info repository; lazily initialized
2424     private volatile transient ClassRepository genericInfo;
2425 
2426     // accessor for factory


2429         return CoreReflectionFactory.make(this, ClassScope.make(this));
2430     }
2431 
2432     // accessor for generic info repository;
2433     // generic info is lazily initialized
2434     private ClassRepository getGenericInfo() {
2435         ClassRepository genericInfo = this.genericInfo;
2436         if (genericInfo == null) {
2437             String signature = getGenericSignature0();
2438             if (signature == null) {
2439                 genericInfo = ClassRepository.NONE;
2440             } else {
2441                 genericInfo = ClassRepository.make(signature, getFactory());
2442             }
2443             this.genericInfo = genericInfo;
2444         }
2445         return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
2446     }
2447 
2448     // Annotations handling
2449     native byte[] getRawAnnotations();
2450     // Since 1.8
2451     native byte[] getRawTypeAnnotations();
2452     static byte[] getExecutableTypeAnnotationBytes(Executable ex) {
2453         return getReflectionFactory().getExecutableTypeAnnotationBytes(ex);
2454     }
2455 
2456     native ConstantPool getConstantPool();
2457 
2458     //
2459     //
2460     // java.lang.reflect.Field handling
2461     //
2462     //
2463 
2464     // Returns an array of "root" fields. These Field objects must NOT
2465     // be propagated to the outside world, but must instead be copied
2466     // via ReflectionFactory.copyField.
2467     private Field[] privateGetDeclaredFields(boolean publicOnly) {
2468         checkInitted();
2469         Field[] res;


3289             return;
3290         declaredAnnotations = AnnotationParser.parseAnnotations(
3291             getRawAnnotations(), getConstantPool(), this);
3292         Class<?> superClass = getSuperclass();
3293         if (superClass == null) {
3294             annotations = declaredAnnotations;
3295         } else {
3296             annotations = new HashMap<>();
3297             superClass.initAnnotationsIfNecessary();
3298             for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3299                 Class<? extends Annotation> annotationClass = e.getKey();
3300                 if (AnnotationType.getInstance(annotationClass).isInherited())
3301                     annotations.put(annotationClass, e.getValue());
3302             }
3303             annotations.putAll(declaredAnnotations);
3304         }
3305     }
3306 
3307     // Annotation types cache their internal (AnnotationType) form
3308 
3309     @SuppressWarnings("UnusedDeclaration")
3310     private volatile transient AnnotationType annotationType;
3311 
3312     boolean casAnnotationType(AnnotationType oldType, AnnotationType newType) {
3313         return Atomic.casAnnotationType(this, oldType, newType);
3314     }
3315 
3316     AnnotationType getAnnotationType() {
3317         return annotationType;
3318     }
3319 
3320     /* Backing store of user-defined values pertaining to this class.
3321      * Maintained by the ClassValue class.
3322      */
3323     transient ClassValue.ClassValueMap classValueMap;
3324 
3325     /**
3326      * Returns an AnnotatedType object that represents the use of a type to specify
3327      * the superclass of the entity represented by this Class. (The <em>use</em> of type
3328      * Foo to specify the superclass in '... extends Foo' is distinct from the
3329      * <em>declaration</em> of type Foo.)
3330      *
3331      * If this Class represents a class type whose declaration does not explicitly
3332      * indicate an annotated superclass, the return value is null.
3333      *