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

Print this page
rev 3186 : 6880112: Project Coin: Port JDK core library code to use diamond operator


1289      *
1290      *             </ul>
1291      *
1292      * @since JDK1.1
1293      */
1294     public Class<?>[] getClasses() {
1295         // be very careful not to change the stack depth of this
1296         // checkMemberAccess call for security reasons
1297         // see java.lang.SecurityManager.checkMemberAccess
1298         checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1299 
1300         // Privileged so this implementation can look at DECLARED classes,
1301         // something the caller might not have privilege to do.  The code here
1302         // is allowed to look at DECLARED classes because (1) it does not hand
1303         // out anything other than public members and (2) public member access
1304         // has already been ok'd by the SecurityManager.
1305 
1306         return java.security.AccessController.doPrivileged(
1307             new java.security.PrivilegedAction<Class<?>[]>() {
1308                 public Class[] run() {
1309                     List<Class<?>> list = new ArrayList<Class<?>>();
1310                     Class<?> currentClass = Class.this;
1311                     while (currentClass != null) {
1312                         Class<?>[] members = currentClass.getDeclaredClasses();
1313                         for (int i = 0; i < members.length; i++) {
1314                             if (Modifier.isPublic(members[i].getModifiers())) {
1315                                 list.add(members[i]);
1316                             }
1317                         }
1318                         currentClass = currentClass.getSuperclass();
1319                     }
1320                     return list.toArray(new Class[0]);
1321                 }
1322             });
1323     }
1324 
1325 
1326     /**
1327      * Returns an array containing {@code Field} objects reflecting all
1328      * the accessible public fields of the class or interface represented by
1329      * this {@code Class} object.  The elements in the array returned are


2289     private Field[] privateGetDeclaredFields(boolean publicOnly) {
2290         checkInitted();
2291         Field[] res = null;
2292         if (useCaches) {
2293             clearCachesOnClassRedefinition();
2294             if (publicOnly) {
2295                 if (declaredPublicFields != null) {
2296                     res = declaredPublicFields.get();
2297                 }
2298             } else {
2299                 if (declaredFields != null) {
2300                     res = declaredFields.get();
2301                 }
2302             }
2303             if (res != null) return res;
2304         }
2305         // No cached value available; request value from VM
2306         res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2307         if (useCaches) {
2308             if (publicOnly) {
2309                 declaredPublicFields = new SoftReference<Field[]>(res);
2310             } else {
2311                 declaredFields = new SoftReference<Field[]>(res);
2312             }
2313         }
2314         return res;
2315     }
2316 
2317     // Returns an array of "root" fields. These Field objects must NOT
2318     // be propagated to the outside world, but must instead be copied
2319     // via ReflectionFactory.copyField.
2320     private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2321         checkInitted();
2322         Field[] res = null;
2323         if (useCaches) {
2324             clearCachesOnClassRedefinition();
2325             if (publicFields != null) {
2326                 res = publicFields.get();
2327             }
2328             if (res != null) return res;
2329         }
2330 
2331         // No cached value available; compute value recursively.
2332         // Traverse in correct order for getField().
2333         List<Field> fields = new ArrayList<Field>();
2334         if (traversedInterfaces == null) {
2335             traversedInterfaces = new HashSet<Class<?>>();
2336         }
2337 
2338         // Local fields
2339         Field[] tmp = privateGetDeclaredFields(true);
2340         addAll(fields, tmp);
2341 
2342         // Direct superinterfaces, recursively
2343         for (Class<?> c : getInterfaces()) {
2344             if (!traversedInterfaces.contains(c)) {
2345                 traversedInterfaces.add(c);
2346                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2347             }
2348         }
2349 
2350         // Direct superclass, recursively
2351         if (!isInterface()) {
2352             Class<?> c = getSuperclass();
2353             if (c != null) {
2354                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2355             }
2356         }
2357 
2358         res = new Field[fields.size()];
2359         fields.toArray(res);
2360         if (useCaches) {
2361             publicFields = new SoftReference<Field[]>(res);
2362         }
2363         return res;
2364     }
2365 
2366     private static void addAll(Collection<Field> c, Field[] o) {
2367         for (int i = 0; i < o.length; i++) {
2368             c.add(o[i]);
2369         }
2370     }
2371 
2372 
2373     //
2374     //
2375     // java.lang.reflect.Constructor handling
2376     //
2377     //
2378 
2379     // Returns an array of "root" constructors. These Constructor
2380     // objects must NOT be propagated to the outside world, but must
2381     // instead be copied via ReflectionFactory.copyConstructor.


2386             clearCachesOnClassRedefinition();
2387             if (publicOnly) {
2388                 if (publicConstructors != null) {
2389                     res = publicConstructors.get();
2390                 }
2391             } else {
2392                 if (declaredConstructors != null) {
2393                     res = declaredConstructors.get();
2394                 }
2395             }
2396             if (res != null) return res;
2397         }
2398         // No cached value available; request value from VM
2399         if (isInterface()) {
2400             res = new Constructor[0];
2401         } else {
2402             res = getDeclaredConstructors0(publicOnly);
2403         }
2404         if (useCaches) {
2405             if (publicOnly) {
2406                 publicConstructors = new SoftReference<Constructor<T>[]>(res);
2407             } else {
2408                 declaredConstructors = new SoftReference<Constructor<T>[]>(res);
2409             }
2410         }
2411         return res;
2412     }
2413 
2414     //
2415     //
2416     // java.lang.reflect.Method handling
2417     //
2418     //
2419 
2420     // Returns an array of "root" methods. These Method objects must NOT
2421     // be propagated to the outside world, but must instead be copied
2422     // via ReflectionFactory.copyMethod.
2423     private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2424         checkInitted();
2425         Method[] res = null;
2426         if (useCaches) {
2427             clearCachesOnClassRedefinition();
2428             if (publicOnly) {
2429                 if (declaredPublicMethods != null) {
2430                     res = declaredPublicMethods.get();
2431                 }
2432             } else {
2433                 if (declaredMethods != null) {
2434                     res = declaredMethods.get();
2435                 }
2436             }
2437             if (res != null) return res;
2438         }
2439         // No cached value available; request value from VM
2440         res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2441         if (useCaches) {
2442             if (publicOnly) {
2443                 declaredPublicMethods = new SoftReference<Method[]>(res);
2444             } else {
2445                 declaredMethods = new SoftReference<Method[]>(res);
2446             }
2447         }
2448         return res;
2449     }
2450 
2451     static class MethodArray {
2452         private Method[] methods;
2453         private int length;
2454 
2455         MethodArray() {
2456             methods = new Method[20];
2457             length = 0;
2458         }
2459 
2460         void add(Method m) {
2461             if (length == methods.length) {
2462                 methods = Arrays.copyOf(methods, 2 * methods.length);
2463             }
2464             methods[length++] = m;
2465         }


2581                     if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2582                         inheritedMethods.removeByNameAndSignature(m);
2583                     }
2584                 }
2585                 // Insert superclass's inherited methods before
2586                 // superinterfaces' to satisfy getMethod's search
2587                 // order
2588                 supers.addAll(inheritedMethods);
2589                 inheritedMethods = supers;
2590             }
2591         }
2592         // Filter out all local methods from inherited ones
2593         for (int i = 0; i < methods.length(); i++) {
2594             Method m = methods.get(i);
2595             inheritedMethods.removeByNameAndSignature(m);
2596         }
2597         methods.addAllIfNotPresent(inheritedMethods);
2598         methods.compactAndTrim();
2599         res = methods.getArray();
2600         if (useCaches) {
2601             publicMethods = new SoftReference<Method[]>(res);
2602         }
2603         return res;
2604     }
2605 
2606 
2607     //
2608     // Helpers for fetchers of one field, method, or constructor
2609     //
2610 
2611     private Field searchFields(Field[] fields, String name) {
2612         String internedName = name.intern();
2613         for (int i = 0; i < fields.length; i++) {
2614             if (fields[i].getName() == internedName) {
2615                 return getReflectionFactory().copyField(fields[i]);
2616             }
2617         }
2618         return null;
2619     }
2620 
2621     private Field getField0(String name) throws NoSuchFieldException {


2960             catch (NoSuchMethodException ex) { return null; }
2961             catch (IllegalAccessException ex) { return null; }
2962         }
2963         return enumConstants;
2964     }
2965     private volatile transient T[] enumConstants = null;
2966 
2967     /**
2968      * Returns a map from simple name to enum constant.  This package-private
2969      * method is used internally by Enum to implement
2970      *     public static <T extends Enum<T>> T valueOf(Class<T>, String)
2971      * efficiently.  Note that the map is returned by this method is
2972      * created lazily on first use.  Typically it won't ever get created.
2973      */
2974     Map<String, T> enumConstantDirectory() {
2975         if (enumConstantDirectory == null) {
2976             T[] universe = getEnumConstantsShared();
2977             if (universe == null)
2978                 throw new IllegalArgumentException(
2979                     getName() + " is not an enum type");
2980             Map<String, T> m = new HashMap<String, T>(2 * universe.length);
2981             for (T constant : universe)
2982                 m.put(((Enum<?>)constant).name(), constant);
2983             enumConstantDirectory = m;
2984         }
2985         return enumConstantDirectory;
2986     }
2987     private volatile transient Map<String, T> enumConstantDirectory = null;
2988 
2989     /**
2990      * Casts an object to the class or interface represented
2991      * by this {@code Class} object.
2992      *
2993      * @param obj the object to be cast
2994      * @return the object after casting, or null if obj is null
2995      *
2996      * @throws ClassCastException if the object is not
2997      * null and is not assignable to the type T.
2998      *
2999      * @since 1.5
3000      */


3073      */
3074     public Annotation[] getDeclaredAnnotations()  {
3075         initAnnotationsIfNecessary();
3076         return AnnotationParser.toArray(declaredAnnotations);
3077     }
3078 
3079     // Annotations cache
3080     private transient Map<Class<? extends Annotation>, Annotation> annotations;
3081     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
3082 
3083     private synchronized void initAnnotationsIfNecessary() {
3084         clearCachesOnClassRedefinition();
3085         if (annotations != null)
3086             return;
3087         declaredAnnotations = AnnotationParser.parseAnnotations(
3088             getRawAnnotations(), getConstantPool(), this);
3089         Class<?> superClass = getSuperclass();
3090         if (superClass == null) {
3091             annotations = declaredAnnotations;
3092         } else {
3093             annotations = new HashMap<Class<? extends Annotation>, Annotation>();
3094             superClass.initAnnotationsIfNecessary();
3095             for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3096                 Class<? extends Annotation> annotationClass = e.getKey();
3097                 if (AnnotationType.getInstance(annotationClass).isInherited())
3098                     annotations.put(annotationClass, e.getValue());
3099             }
3100             annotations.putAll(declaredAnnotations);
3101         }
3102     }
3103 
3104     // Annotation types cache their internal (AnnotationType) form
3105 
3106     private AnnotationType annotationType;
3107 
3108     void setAnnotationType(AnnotationType type) {
3109         annotationType = type;
3110     }
3111 
3112     AnnotationType getAnnotationType() {
3113         return annotationType;


1289      *
1290      *             </ul>
1291      *
1292      * @since JDK1.1
1293      */
1294     public Class<?>[] getClasses() {
1295         // be very careful not to change the stack depth of this
1296         // checkMemberAccess call for security reasons
1297         // see java.lang.SecurityManager.checkMemberAccess
1298         checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1299 
1300         // Privileged so this implementation can look at DECLARED classes,
1301         // something the caller might not have privilege to do.  The code here
1302         // is allowed to look at DECLARED classes because (1) it does not hand
1303         // out anything other than public members and (2) public member access
1304         // has already been ok'd by the SecurityManager.
1305 
1306         return java.security.AccessController.doPrivileged(
1307             new java.security.PrivilegedAction<Class<?>[]>() {
1308                 public Class[] run() {
1309                     List<Class<?>> list = new ArrayList<>();
1310                     Class<?> currentClass = Class.this;
1311                     while (currentClass != null) {
1312                         Class<?>[] members = currentClass.getDeclaredClasses();
1313                         for (int i = 0; i < members.length; i++) {
1314                             if (Modifier.isPublic(members[i].getModifiers())) {
1315                                 list.add(members[i]);
1316                             }
1317                         }
1318                         currentClass = currentClass.getSuperclass();
1319                     }
1320                     return list.toArray(new Class[0]);
1321                 }
1322             });
1323     }
1324 
1325 
1326     /**
1327      * Returns an array containing {@code Field} objects reflecting all
1328      * the accessible public fields of the class or interface represented by
1329      * this {@code Class} object.  The elements in the array returned are


2289     private Field[] privateGetDeclaredFields(boolean publicOnly) {
2290         checkInitted();
2291         Field[] res = null;
2292         if (useCaches) {
2293             clearCachesOnClassRedefinition();
2294             if (publicOnly) {
2295                 if (declaredPublicFields != null) {
2296                     res = declaredPublicFields.get();
2297                 }
2298             } else {
2299                 if (declaredFields != null) {
2300                     res = declaredFields.get();
2301                 }
2302             }
2303             if (res != null) return res;
2304         }
2305         // No cached value available; request value from VM
2306         res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2307         if (useCaches) {
2308             if (publicOnly) {
2309                 declaredPublicFields = new SoftReference<>(res);
2310             } else {
2311                 declaredFields = new SoftReference<>(res);
2312             }
2313         }
2314         return res;
2315     }
2316 
2317     // Returns an array of "root" fields. These Field objects must NOT
2318     // be propagated to the outside world, but must instead be copied
2319     // via ReflectionFactory.copyField.
2320     private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2321         checkInitted();
2322         Field[] res = null;
2323         if (useCaches) {
2324             clearCachesOnClassRedefinition();
2325             if (publicFields != null) {
2326                 res = publicFields.get();
2327             }
2328             if (res != null) return res;
2329         }
2330 
2331         // No cached value available; compute value recursively.
2332         // Traverse in correct order for getField().
2333         List<Field> fields = new ArrayList<>();
2334         if (traversedInterfaces == null) {
2335             traversedInterfaces = new HashSet<>();
2336         }
2337 
2338         // Local fields
2339         Field[] tmp = privateGetDeclaredFields(true);
2340         addAll(fields, tmp);
2341 
2342         // Direct superinterfaces, recursively
2343         for (Class<?> c : getInterfaces()) {
2344             if (!traversedInterfaces.contains(c)) {
2345                 traversedInterfaces.add(c);
2346                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2347             }
2348         }
2349 
2350         // Direct superclass, recursively
2351         if (!isInterface()) {
2352             Class<?> c = getSuperclass();
2353             if (c != null) {
2354                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2355             }
2356         }
2357 
2358         res = new Field[fields.size()];
2359         fields.toArray(res);
2360         if (useCaches) {
2361             publicFields = new SoftReference<>(res);
2362         }
2363         return res;
2364     }
2365 
2366     private static void addAll(Collection<Field> c, Field[] o) {
2367         for (int i = 0; i < o.length; i++) {
2368             c.add(o[i]);
2369         }
2370     }
2371 
2372 
2373     //
2374     //
2375     // java.lang.reflect.Constructor handling
2376     //
2377     //
2378 
2379     // Returns an array of "root" constructors. These Constructor
2380     // objects must NOT be propagated to the outside world, but must
2381     // instead be copied via ReflectionFactory.copyConstructor.


2386             clearCachesOnClassRedefinition();
2387             if (publicOnly) {
2388                 if (publicConstructors != null) {
2389                     res = publicConstructors.get();
2390                 }
2391             } else {
2392                 if (declaredConstructors != null) {
2393                     res = declaredConstructors.get();
2394                 }
2395             }
2396             if (res != null) return res;
2397         }
2398         // No cached value available; request value from VM
2399         if (isInterface()) {
2400             res = new Constructor[0];
2401         } else {
2402             res = getDeclaredConstructors0(publicOnly);
2403         }
2404         if (useCaches) {
2405             if (publicOnly) {
2406                 publicConstructors = new SoftReference<>(res);
2407             } else {
2408                 declaredConstructors = new SoftReference<>(res);
2409             }
2410         }
2411         return res;
2412     }
2413 
2414     //
2415     //
2416     // java.lang.reflect.Method handling
2417     //
2418     //
2419 
2420     // Returns an array of "root" methods. These Method objects must NOT
2421     // be propagated to the outside world, but must instead be copied
2422     // via ReflectionFactory.copyMethod.
2423     private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2424         checkInitted();
2425         Method[] res = null;
2426         if (useCaches) {
2427             clearCachesOnClassRedefinition();
2428             if (publicOnly) {
2429                 if (declaredPublicMethods != null) {
2430                     res = declaredPublicMethods.get();
2431                 }
2432             } else {
2433                 if (declaredMethods != null) {
2434                     res = declaredMethods.get();
2435                 }
2436             }
2437             if (res != null) return res;
2438         }
2439         // No cached value available; request value from VM
2440         res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2441         if (useCaches) {
2442             if (publicOnly) {
2443                 declaredPublicMethods = new SoftReference<>(res);
2444             } else {
2445                 declaredMethods = new SoftReference<>(res);
2446             }
2447         }
2448         return res;
2449     }
2450 
2451     static class MethodArray {
2452         private Method[] methods;
2453         private int length;
2454 
2455         MethodArray() {
2456             methods = new Method[20];
2457             length = 0;
2458         }
2459 
2460         void add(Method m) {
2461             if (length == methods.length) {
2462                 methods = Arrays.copyOf(methods, 2 * methods.length);
2463             }
2464             methods[length++] = m;
2465         }


2581                     if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2582                         inheritedMethods.removeByNameAndSignature(m);
2583                     }
2584                 }
2585                 // Insert superclass's inherited methods before
2586                 // superinterfaces' to satisfy getMethod's search
2587                 // order
2588                 supers.addAll(inheritedMethods);
2589                 inheritedMethods = supers;
2590             }
2591         }
2592         // Filter out all local methods from inherited ones
2593         for (int i = 0; i < methods.length(); i++) {
2594             Method m = methods.get(i);
2595             inheritedMethods.removeByNameAndSignature(m);
2596         }
2597         methods.addAllIfNotPresent(inheritedMethods);
2598         methods.compactAndTrim();
2599         res = methods.getArray();
2600         if (useCaches) {
2601             publicMethods = new SoftReference<>(res);
2602         }
2603         return res;
2604     }
2605 
2606 
2607     //
2608     // Helpers for fetchers of one field, method, or constructor
2609     //
2610 
2611     private Field searchFields(Field[] fields, String name) {
2612         String internedName = name.intern();
2613         for (int i = 0; i < fields.length; i++) {
2614             if (fields[i].getName() == internedName) {
2615                 return getReflectionFactory().copyField(fields[i]);
2616             }
2617         }
2618         return null;
2619     }
2620 
2621     private Field getField0(String name) throws NoSuchFieldException {


2960             catch (NoSuchMethodException ex) { return null; }
2961             catch (IllegalAccessException ex) { return null; }
2962         }
2963         return enumConstants;
2964     }
2965     private volatile transient T[] enumConstants = null;
2966 
2967     /**
2968      * Returns a map from simple name to enum constant.  This package-private
2969      * method is used internally by Enum to implement
2970      *     public static <T extends Enum<T>> T valueOf(Class<T>, String)
2971      * efficiently.  Note that the map is returned by this method is
2972      * created lazily on first use.  Typically it won't ever get created.
2973      */
2974     Map<String, T> enumConstantDirectory() {
2975         if (enumConstantDirectory == null) {
2976             T[] universe = getEnumConstantsShared();
2977             if (universe == null)
2978                 throw new IllegalArgumentException(
2979                     getName() + " is not an enum type");
2980             Map<String, T> m = new HashMap<>(2 * universe.length);
2981             for (T constant : universe)
2982                 m.put(((Enum<?>)constant).name(), constant);
2983             enumConstantDirectory = m;
2984         }
2985         return enumConstantDirectory;
2986     }
2987     private volatile transient Map<String, T> enumConstantDirectory = null;
2988 
2989     /**
2990      * Casts an object to the class or interface represented
2991      * by this {@code Class} object.
2992      *
2993      * @param obj the object to be cast
2994      * @return the object after casting, or null if obj is null
2995      *
2996      * @throws ClassCastException if the object is not
2997      * null and is not assignable to the type T.
2998      *
2999      * @since 1.5
3000      */


3073      */
3074     public Annotation[] getDeclaredAnnotations()  {
3075         initAnnotationsIfNecessary();
3076         return AnnotationParser.toArray(declaredAnnotations);
3077     }
3078 
3079     // Annotations cache
3080     private transient Map<Class<? extends Annotation>, Annotation> annotations;
3081     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
3082 
3083     private synchronized void initAnnotationsIfNecessary() {
3084         clearCachesOnClassRedefinition();
3085         if (annotations != null)
3086             return;
3087         declaredAnnotations = AnnotationParser.parseAnnotations(
3088             getRawAnnotations(), getConstantPool(), this);
3089         Class<?> superClass = getSuperclass();
3090         if (superClass == null) {
3091             annotations = declaredAnnotations;
3092         } else {
3093             annotations = new HashMap<>();
3094             superClass.initAnnotationsIfNecessary();
3095             for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3096                 Class<? extends Annotation> annotationClass = e.getKey();
3097                 if (AnnotationType.getInstance(annotationClass).isInherited())
3098                     annotations.put(annotationClass, e.getValue());
3099             }
3100             annotations.putAll(declaredAnnotations);
3101         }
3102     }
3103 
3104     // Annotation types cache their internal (AnnotationType) form
3105 
3106     private AnnotationType annotationType;
3107 
3108     void setAnnotationType(AnnotationType type) {
3109         annotationType = type;
3110     }
3111 
3112     AnnotationType getAnnotationType() {
3113         return annotationType;