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;
|