1 /*
2 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
2321 return name;
2322 }
2323 if (!name.startsWith("/")) {
2324 Class<?> c = this;
2325 while (c.isArray()) {
2326 c = c.getComponentType();
2327 }
2328 String baseName = c.getName();
2329 int index = baseName.lastIndexOf('.');
2330 if (index != -1) {
2331 name = baseName.substring(0, index).replace('.', '/')
2332 +"/"+name;
2333 }
2334 } else {
2335 name = name.substring(1);
2336 }
2337 return name;
2338 }
2339
2340 /**
2341 * Reflection support.
2342 */
2343
2344 // Caches for certain reflective results
2345 private static boolean useCaches = true;
2346 private volatile transient SoftReference<Field[]> declaredFields;
2347 private volatile transient SoftReference<Field[]> publicFields;
2348 private volatile transient SoftReference<Method[]> declaredMethods;
2349 private volatile transient SoftReference<Method[]> publicMethods;
2350 private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
2351 private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
2352 // Intermediate results for getFields and getMethods
2353 private volatile transient SoftReference<Field[]> declaredPublicFields;
2354 private volatile transient SoftReference<Method[]> declaredPublicMethods;
2355
2356 // Incremented by the VM on each call to JVM TI RedefineClasses()
2357 // that redefines this class or a superclass.
2358 private volatile transient int classRedefinedCount = 0;
2359
2360 // Value of classRedefinedCount when we last cleared the cached values
2361 // that are sensitive to class redefinition.
2362 private volatile transient int lastRedefinedCount = 0;
2363
2364 // Clears cached values that might possibly have been obsoleted by
2365 // a class redefinition.
2366 private void clearCachesOnClassRedefinition() {
2367 if (lastRedefinedCount != classRedefinedCount) {
2368 declaredFields = publicFields = declaredPublicFields = null;
2369 declaredMethods = publicMethods = declaredPublicMethods = null;
2370 declaredConstructors = publicConstructors = null;
2371 annotations = declaredAnnotations = null;
2372
2373 // Use of "volatile" (and synchronization by caller in the case
2374 // of annotations) ensures that no thread sees the update to
2375 // lastRedefinedCount before seeing the caches cleared.
2376 // We do not guard against brief windows during which multiple
2377 // threads might redundantly work to fill an empty cache.
2378 lastRedefinedCount = classRedefinedCount;
2379 }
2380 }
2381
2382 // Generic signature handling
2383 private native String getGenericSignature();
2384
2385 // Generic info repository; lazily initialized
2386 private transient ClassRepository genericInfo;
2387
2388 // accessor for factory
2389 private GenericsFactory getFactory() {
2390 // create scope and factory
2391 return CoreReflectionFactory.make(this, ClassScope.make(this));
2392 }
2393
2394 // accessor for generic info repository
2395 private ClassRepository getGenericInfo() {
2396 // lazily initialize repository if necessary
2397 if (genericInfo == null) {
2398 // create and cache generic info repository
2399 genericInfo = ClassRepository.make(getGenericSignature(),
2400 getFactory());
2401 }
2402 return genericInfo; //return cached repository
2403 }
2404
2405 // Annotations handling
2406 private native byte[] getRawAnnotations();
2407
2408 native ConstantPool getConstantPool();
2409
2410 //
2411 //
2412 // java.lang.reflect.Field handling
2413 //
2414 //
2415
2416 // Returns an array of "root" fields. These Field objects must NOT
2417 // be propagated to the outside world, but must instead be copied
2418 // via ReflectionFactory.copyField.
2419 private Field[] privateGetDeclaredFields(boolean publicOnly) {
2420 checkInitted();
2421 Field[] res = null;
2422 if (useCaches) {
2423 clearCachesOnClassRedefinition();
2424 if (publicOnly) {
2425 if (declaredPublicFields != null) {
2426 res = declaredPublicFields.get();
2427 }
2428 } else {
2429 if (declaredFields != null) {
2430 res = declaredFields.get();
2431 }
2432 }
2433 if (res != null) return res;
2434 }
2435 // No cached value available; request value from VM
2436 res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2437 if (useCaches) {
2438 if (publicOnly) {
2439 declaredPublicFields = new SoftReference<>(res);
2440 } else {
2441 declaredFields = new SoftReference<>(res);
2442 }
2443 }
2444 return res;
2445 }
2446
2447 // Returns an array of "root" fields. These Field objects must NOT
2448 // be propagated to the outside world, but must instead be copied
2449 // via ReflectionFactory.copyField.
2450 private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2451 checkInitted();
2452 Field[] res = null;
2453 if (useCaches) {
2454 clearCachesOnClassRedefinition();
2455 if (publicFields != null) {
2456 res = publicFields.get();
2457 }
2458 if (res != null) return res;
2459 }
2460
2461 // No cached value available; compute value recursively.
2462 // Traverse in correct order for getField().
2463 List<Field> fields = new ArrayList<>();
2464 if (traversedInterfaces == null) {
2465 traversedInterfaces = new HashSet<>();
2466 }
2467
2468 // Local fields
2469 Field[] tmp = privateGetDeclaredFields(true);
2470 addAll(fields, tmp);
2471
2472 // Direct superinterfaces, recursively
2473 for (Class<?> c : getInterfaces()) {
2474 if (!traversedInterfaces.contains(c)) {
2475 traversedInterfaces.add(c);
2476 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2477 }
2478 }
2479
2480 // Direct superclass, recursively
2481 if (!isInterface()) {
2482 Class<?> c = getSuperclass();
2483 if (c != null) {
2484 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2485 }
2486 }
2487
2488 res = new Field[fields.size()];
2489 fields.toArray(res);
2490 if (useCaches) {
2491 publicFields = new SoftReference<>(res);
2492 }
2493 return res;
2494 }
2495
2496 private static void addAll(Collection<Field> c, Field[] o) {
2497 for (int i = 0; i < o.length; i++) {
2498 c.add(o[i]);
2499 }
2500 }
2501
2502
2503 //
2504 //
2505 // java.lang.reflect.Constructor handling
2506 //
2507 //
2508
2509 // Returns an array of "root" constructors. These Constructor
2510 // objects must NOT be propagated to the outside world, but must
2511 // instead be copied via ReflectionFactory.copyConstructor.
2512 private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
2513 checkInitted();
2514 Constructor<T>[] res = null;
2515 if (useCaches) {
2516 clearCachesOnClassRedefinition();
2517 if (publicOnly) {
2518 if (publicConstructors != null) {
2519 res = publicConstructors.get();
2520 }
2521 } else {
2522 if (declaredConstructors != null) {
2523 res = declaredConstructors.get();
2524 }
2525 }
2526 if (res != null) return res;
2527 }
2528 // No cached value available; request value from VM
2529 if (isInterface()) {
2530 res = new Constructor[0];
2531 } else {
2532 res = getDeclaredConstructors0(publicOnly);
2533 }
2534 if (useCaches) {
2535 if (publicOnly) {
2536 publicConstructors = new SoftReference<>(res);
2537 } else {
2538 declaredConstructors = new SoftReference<>(res);
2539 }
2540 }
2541 return res;
2542 }
2543
2544 //
2545 //
2546 // java.lang.reflect.Method handling
2547 //
2548 //
2549
2550 // Returns an array of "root" methods. These Method objects must NOT
2551 // be propagated to the outside world, but must instead be copied
2552 // via ReflectionFactory.copyMethod.
2553 private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2554 checkInitted();
2555 Method[] res = null;
2556 if (useCaches) {
2557 clearCachesOnClassRedefinition();
2558 if (publicOnly) {
2559 if (declaredPublicMethods != null) {
2560 res = declaredPublicMethods.get();
2561 }
2562 } else {
2563 if (declaredMethods != null) {
2564 res = declaredMethods.get();
2565 }
2566 }
2567 if (res != null) return res;
2568 }
2569 // No cached value available; request value from VM
2570 res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2571 if (useCaches) {
2572 if (publicOnly) {
2573 declaredPublicMethods = new SoftReference<>(res);
2574 } else {
2575 declaredMethods = new SoftReference<>(res);
2576 }
2577 }
2578 return res;
2579 }
2580
2581 static class MethodArray {
2582 private Method[] methods;
2583 private int length;
2584
2585 MethodArray() {
2586 methods = new Method[20];
2587 length = 0;
2588 }
2589
2590 void add(Method m) {
2591 if (length == methods.length) {
2592 methods = Arrays.copyOf(methods, 2 * methods.length);
2593 }
2594 methods[length++] = m;
2595 }
2657 }
2658 newPos++;
2659 }
2660 }
2661 if (newPos != methods.length) {
2662 methods = Arrays.copyOf(methods, newPos);
2663 }
2664 }
2665
2666 Method[] getArray() {
2667 return methods;
2668 }
2669 }
2670
2671
2672 // Returns an array of "root" methods. These Method objects must NOT
2673 // be propagated to the outside world, but must instead be copied
2674 // via ReflectionFactory.copyMethod.
2675 private Method[] privateGetPublicMethods() {
2676 checkInitted();
2677 Method[] res = null;
2678 if (useCaches) {
2679 clearCachesOnClassRedefinition();
2680 if (publicMethods != null) {
2681 res = publicMethods.get();
2682 }
2683 if (res != null) return res;
2684 }
2685
2686 // No cached value available; compute value recursively.
2687 // Start by fetching public declared methods
2688 MethodArray methods = new MethodArray();
2689 {
2690 Method[] tmp = privateGetDeclaredMethods(true);
2691 methods.addAll(tmp);
2692 }
2693 // Now recur over superclass and direct superinterfaces.
2694 // Go over superinterfaces first so we can more easily filter
2695 // out concrete implementations inherited from superclasses at
2696 // the end.
2697 MethodArray inheritedMethods = new MethodArray();
2698 Class<?>[] interfaces = getInterfaces();
2699 for (int i = 0; i < interfaces.length; i++) {
2700 inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
2701 }
2702 if (!isInterface()) {
2710 Method m = supers.get(i);
2711 if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2712 inheritedMethods.removeByNameAndSignature(m);
2713 }
2714 }
2715 // Insert superclass's inherited methods before
2716 // superinterfaces' to satisfy getMethod's search
2717 // order
2718 supers.addAll(inheritedMethods);
2719 inheritedMethods = supers;
2720 }
2721 }
2722 // Filter out all local methods from inherited ones
2723 for (int i = 0; i < methods.length(); i++) {
2724 Method m = methods.get(i);
2725 inheritedMethods.removeByNameAndSignature(m);
2726 }
2727 methods.addAllIfNotPresent(inheritedMethods);
2728 methods.compactAndTrim();
2729 res = methods.getArray();
2730 if (useCaches) {
2731 publicMethods = new SoftReference<>(res);
2732 }
2733 return res;
2734 }
2735
2736
2737 //
2738 // Helpers for fetchers of one field, method, or constructor
2739 //
2740
2741 private Field searchFields(Field[] fields, String name) {
2742 String internedName = name.intern();
2743 for (int i = 0; i < fields.length; i++) {
2744 if (fields[i].getName() == internedName) {
2745 return getReflectionFactory().copyField(fields[i]);
2746 }
2747 }
2748 return null;
2749 }
2750
2751 private Field getField0(String name) throws NoSuchFieldException {
2752 // Note: the intent is that the search algorithm this routine
2753 // uses be equivalent to the ordering imposed by
2754 // privateGetPublicFields(). It fetches only the declared
2755 // public fields for each class, however, to reduce the number
2756 // of Field objects which have to be created for the common
2757 // case where the field being requested is declared in the
2758 // class which is being queried.
2759 Field res = null;
2760 // Search declared public fields
2761 if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
2762 return res;
2763 }
2764 // Direct superinterfaces, recursively
2765 Class<?>[] interfaces = getInterfaces();
2766 for (int i = 0; i < interfaces.length; i++) {
2767 Class<?> c = interfaces[i];
2768 if ((res = c.getField0(name)) != null) {
2769 return res;
2770 }
2771 }
2772 // Direct superclass, recursively
2773 if (!isInterface()) {
2774 Class<?> c = getSuperclass();
2775 if (c != null) {
2776 if ((res = c.getField0(name)) != null) {
2777 return res;
2778 }
2779 }
2791 Method m = methods[i];
2792 if (m.getName() == internedName
2793 && arrayContentsEq(parameterTypes, m.getParameterTypes())
2794 && (res == null
2795 || res.getReturnType().isAssignableFrom(m.getReturnType())))
2796 res = m;
2797 }
2798
2799 return (res == null ? res : getReflectionFactory().copyMethod(res));
2800 }
2801
2802
2803 private Method getMethod0(String name, Class<?>[] parameterTypes) {
2804 // Note: the intent is that the search algorithm this routine
2805 // uses be equivalent to the ordering imposed by
2806 // privateGetPublicMethods(). It fetches only the declared
2807 // public methods for each class, however, to reduce the
2808 // number of Method objects which have to be created for the
2809 // common case where the method being requested is declared in
2810 // the class which is being queried.
2811 Method res = null;
2812 // Search declared public methods
2813 if ((res = searchMethods(privateGetDeclaredMethods(true),
2814 name,
2815 parameterTypes)) != null) {
2816 return res;
2817 }
2818 // Search superclass's methods
2819 if (!isInterface()) {
2820 Class<? super T> c = getSuperclass();
2821 if (c != null) {
2822 if ((res = c.getMethod0(name, parameterTypes)) != null) {
2823 return res;
2824 }
2825 }
2826 }
2827 // Search superinterfaces' methods
2828 Class<?>[] interfaces = getInterfaces();
2829 for (int i = 0; i < interfaces.length; i++) {
2830 Class<?> c = interfaces[i];
2831 if ((res = c.getMethod0(name, parameterTypes)) != null) {
3192
3193 /**
3194 * @since 1.5
3195 */
3196 public Annotation[] getAnnotations() {
3197 initAnnotationsIfNecessary();
3198 return AnnotationParser.toArray(annotations);
3199 }
3200
3201 /**
3202 * @since 1.5
3203 */
3204 public Annotation[] getDeclaredAnnotations() {
3205 initAnnotationsIfNecessary();
3206 return AnnotationParser.toArray(declaredAnnotations);
3207 }
3208
3209 // Annotations cache
3210 private transient Map<Class<? extends Annotation>, Annotation> annotations;
3211 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
3212
3213 private synchronized void initAnnotationsIfNecessary() {
3214 clearCachesOnClassRedefinition();
3215 if (annotations != null)
3216 return;
3217 declaredAnnotations = AnnotationParser.parseAnnotations(
3218 getRawAnnotations(), getConstantPool(), this);
3219 Class<?> superClass = getSuperclass();
3220 if (superClass == null) {
3221 annotations = declaredAnnotations;
3222 } else {
3223 annotations = new HashMap<>();
3224 superClass.initAnnotationsIfNecessary();
3225 for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3226 Class<? extends Annotation> annotationClass = e.getKey();
3227 if (AnnotationType.getInstance(annotationClass).isInherited())
3228 annotations.put(annotationClass, e.getValue());
3229 }
3230 annotations.putAll(declaredAnnotations);
3231 }
3232 }
3233
3234 // Annotation types cache their internal (AnnotationType) form
3235
3236 private AnnotationType annotationType;
3237
3238 void setAnnotationType(AnnotationType type) {
3239 annotationType = type;
3240 }
3241
3242 AnnotationType getAnnotationType() {
3243 return annotationType;
3244 }
3245
3246 /* Backing store of user-defined values pertaining to this class.
3247 * Maintained by the ClassValue class.
3248 */
3249 transient ClassValue.ClassValueMap classValueMap;
3250 }
|
1 /*
2 * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
2321 return name;
2322 }
2323 if (!name.startsWith("/")) {
2324 Class<?> c = this;
2325 while (c.isArray()) {
2326 c = c.getComponentType();
2327 }
2328 String baseName = c.getName();
2329 int index = baseName.lastIndexOf('.');
2330 if (index != -1) {
2331 name = baseName.substring(0, index).replace('.', '/')
2332 +"/"+name;
2333 }
2334 } else {
2335 name = name.substring(1);
2336 }
2337 return name;
2338 }
2339
2340 /**
2341 * Atomic operations support.
2342 */
2343 private static class Atomic {
2344 // initialize Unsafe machinery here, since we need to call Class.class instance method
2345 // and have to avoid calling it in the static initializer of the Class class...
2346 private static final Unsafe unsafe = Unsafe.getUnsafe();
2347 // offset of Class.reflectionData instance field
2348 private static final long reflectionDataOffset;
2349 // offset of Class.annotationType instance field
2350 private static final long annotationTypeOffset;
2351
2352 static {
2353 Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches
2354 reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
2355 annotationTypeOffset = objectFieldOffset(fields, "annotationType");
2356 }
2357
2358 private static long objectFieldOffset(Field[] fields, String fieldName) {
2359 Field field = searchFields(fields, fieldName);
2360 if (field == null) {
2361 throw new Error("No " + fieldName + " field found in java.lang.Class");
2362 }
2363 return unsafe.objectFieldOffset(field);
2364 }
2365
2366 static <T> boolean casReflectionData(Class<?> clazz,
2367 SoftReference<ReflectionData<T>> oldData,
2368 SoftReference<ReflectionData<T>> newData) {
2369 return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
2370 }
2371
2372 static <T> boolean casAnnotationType(Class<?> clazz,
2373 AnnotationType oldType,
2374 AnnotationType newType) {
2375 return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
2376 }
2377 }
2378
2379 /**
2380 * Reflection support.
2381 */
2382
2383 // Caches for certain reflective results
2384 private static boolean useCaches = true;
2385
2386 // reflection data that might get invalidated when JVM TI RedefineClasses() is called
2387 static class ReflectionData<T> {
2388 volatile Field[] declaredFields;
2389 volatile Field[] publicFields;
2390 volatile Method[] declaredMethods;
2391 volatile Method[] publicMethods;
2392 volatile Constructor<T>[] declaredConstructors;
2393 volatile Constructor<T>[] publicConstructors;
2394 // Intermediate results for getFields and getMethods
2395 volatile Field[] declaredPublicFields;
2396 volatile Method[] declaredPublicMethods;
2397 // Value of classRedefinedCount when we created this ReflectionData instance
2398 final int redefinedCount;
2399
2400 ReflectionData(int redefinedCount) {
2401 this.redefinedCount = redefinedCount;
2402 }
2403 }
2404
2405 private volatile transient SoftReference<ReflectionData<T>> reflectionData;
2406
2407 // Incremented by the VM on each call to JVM TI RedefineClasses()
2408 // that redefines this class or a superclass.
2409 private volatile transient int classRedefinedCount = 0;
2410
2411 // Lazily create and cache ReflectionData
2412 private ReflectionData<T> reflectionData() {
2413 SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2414 int classRedefinedCount = this.classRedefinedCount;
2415 ReflectionData<T> rd;
2416 if (useCaches &&
2417 reflectionData != null &&
2418 (rd = reflectionData.get()) != null &&
2419 rd.redefinedCount == classRedefinedCount) {
2420 return rd;
2421 }
2422 // else no SoftReference or cleared SoftReference or stale ReflectionData
2423 // -> create and replace new instance
2424 return newReflectionData(reflectionData, classRedefinedCount);
2425 }
2426
2427 private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
2428 int classRedefinedCount) {
2429 if (!useCaches) return null;
2430
2431 while (true) {
2432 ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2433 // try to CAS it...
2434 if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
2435 return rd;
2436 }
2437 // else retry
2438 oldReflectionData = this.reflectionData;
2439 classRedefinedCount = this.classRedefinedCount;
2440 if (oldReflectionData != null &&
2441 (rd = oldReflectionData.get()) != null &&
2442 rd.redefinedCount == classRedefinedCount) {
2443 return rd;
2444 }
2445 }
2446 }
2447
2448 // Generic signature handling
2449 private native String getGenericSignature();
2450
2451 // Generic info repository; lazily initialized
2452 private transient ClassRepository genericInfo;
2453
2454 // accessor for factory
2455 private GenericsFactory getFactory() {
2456 // create scope and factory
2457 return CoreReflectionFactory.make(this, ClassScope.make(this));
2458 }
2459
2460 // accessor for generic info repository
2461 private ClassRepository getGenericInfo() {
2462 // lazily initialize repository if necessary
2463 if (genericInfo == null) {
2464 // create and cache generic info repository
2465 genericInfo = ClassRepository.make(getGenericSignature(),
2466 getFactory());
2467 }
2468 return genericInfo; //return cached repository
2469 }
2470
2471 // Annotations handling
2472 native byte[] getRawAnnotations();
2473
2474 native ConstantPool getConstantPool();
2475
2476 //
2477 //
2478 // java.lang.reflect.Field handling
2479 //
2480 //
2481
2482 // Returns an array of "root" fields. These Field objects must NOT
2483 // be propagated to the outside world, but must instead be copied
2484 // via ReflectionFactory.copyField.
2485 private Field[] privateGetDeclaredFields(boolean publicOnly) {
2486 checkInitted();
2487 Field[] res;
2488 ReflectionData<T> rd = reflectionData();
2489 if (rd != null) {
2490 res = publicOnly ? rd.declaredPublicFields : rd.declaredFields;
2491 if (res != null) return res;
2492 }
2493 // No cached value available; request value from VM
2494 res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2495 if (rd != null) {
2496 if (publicOnly) {
2497 rd.declaredPublicFields = res;
2498 } else {
2499 rd.declaredFields = res;
2500 }
2501 }
2502 return res;
2503 }
2504
2505 // Returns an array of "root" fields. These Field objects must NOT
2506 // be propagated to the outside world, but must instead be copied
2507 // via ReflectionFactory.copyField.
2508 private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2509 checkInitted();
2510 Field[] res;
2511 ReflectionData<T> rd = reflectionData();
2512 if (rd != null) {
2513 res = rd.publicFields;
2514 if (res != null) return res;
2515 }
2516
2517 // No cached value available; compute value recursively.
2518 // Traverse in correct order for getField().
2519 List<Field> fields = new ArrayList<>();
2520 if (traversedInterfaces == null) {
2521 traversedInterfaces = new HashSet<>();
2522 }
2523
2524 // Local fields
2525 Field[] tmp = privateGetDeclaredFields(true);
2526 addAll(fields, tmp);
2527
2528 // Direct superinterfaces, recursively
2529 for (Class<?> c : getInterfaces()) {
2530 if (!traversedInterfaces.contains(c)) {
2531 traversedInterfaces.add(c);
2532 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2533 }
2534 }
2535
2536 // Direct superclass, recursively
2537 if (!isInterface()) {
2538 Class<?> c = getSuperclass();
2539 if (c != null) {
2540 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2541 }
2542 }
2543
2544 res = new Field[fields.size()];
2545 fields.toArray(res);
2546 if (rd != null) {
2547 rd.publicFields = res;
2548 }
2549 return res;
2550 }
2551
2552 private static void addAll(Collection<Field> c, Field[] o) {
2553 for (int i = 0; i < o.length; i++) {
2554 c.add(o[i]);
2555 }
2556 }
2557
2558
2559 //
2560 //
2561 // java.lang.reflect.Constructor handling
2562 //
2563 //
2564
2565 // Returns an array of "root" constructors. These Constructor
2566 // objects must NOT be propagated to the outside world, but must
2567 // instead be copied via ReflectionFactory.copyConstructor.
2568 private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
2569 checkInitted();
2570 Constructor<T>[] res;
2571 ReflectionData<T> rd = reflectionData();
2572 if (rd != null) {
2573 res = publicOnly ? rd.publicConstructors : rd.declaredConstructors;
2574 if (res != null) return res;
2575 }
2576 // No cached value available; request value from VM
2577 if (isInterface()) {
2578 res = new Constructor[0];
2579 } else {
2580 res = getDeclaredConstructors0(publicOnly);
2581 }
2582 if (rd != null) {
2583 if (publicOnly) {
2584 rd.publicConstructors = res;
2585 } else {
2586 rd.declaredConstructors = res;
2587 }
2588 }
2589 return res;
2590 }
2591
2592 //
2593 //
2594 // java.lang.reflect.Method handling
2595 //
2596 //
2597
2598 // Returns an array of "root" methods. These Method objects must NOT
2599 // be propagated to the outside world, but must instead be copied
2600 // via ReflectionFactory.copyMethod.
2601 private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2602 checkInitted();
2603 Method[] res;
2604 ReflectionData<T> rd = reflectionData();
2605 if (rd != null) {
2606 res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
2607 if (res != null) return res;
2608 }
2609 // No cached value available; request value from VM
2610 res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2611 if (rd != null) {
2612 if (publicOnly) {
2613 rd.declaredPublicMethods = res;
2614 } else {
2615 rd.declaredMethods = res;
2616 }
2617 }
2618 return res;
2619 }
2620
2621 static class MethodArray {
2622 private Method[] methods;
2623 private int length;
2624
2625 MethodArray() {
2626 methods = new Method[20];
2627 length = 0;
2628 }
2629
2630 void add(Method m) {
2631 if (length == methods.length) {
2632 methods = Arrays.copyOf(methods, 2 * methods.length);
2633 }
2634 methods[length++] = m;
2635 }
2697 }
2698 newPos++;
2699 }
2700 }
2701 if (newPos != methods.length) {
2702 methods = Arrays.copyOf(methods, newPos);
2703 }
2704 }
2705
2706 Method[] getArray() {
2707 return methods;
2708 }
2709 }
2710
2711
2712 // Returns an array of "root" methods. These Method objects must NOT
2713 // be propagated to the outside world, but must instead be copied
2714 // via ReflectionFactory.copyMethod.
2715 private Method[] privateGetPublicMethods() {
2716 checkInitted();
2717 Method[] res;
2718 ReflectionData<T> rd = reflectionData();
2719 if (rd != null) {
2720 res = rd.publicMethods;
2721 if (res != null) return res;
2722 }
2723
2724 // No cached value available; compute value recursively.
2725 // Start by fetching public declared methods
2726 MethodArray methods = new MethodArray();
2727 {
2728 Method[] tmp = privateGetDeclaredMethods(true);
2729 methods.addAll(tmp);
2730 }
2731 // Now recur over superclass and direct superinterfaces.
2732 // Go over superinterfaces first so we can more easily filter
2733 // out concrete implementations inherited from superclasses at
2734 // the end.
2735 MethodArray inheritedMethods = new MethodArray();
2736 Class<?>[] interfaces = getInterfaces();
2737 for (int i = 0; i < interfaces.length; i++) {
2738 inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
2739 }
2740 if (!isInterface()) {
2748 Method m = supers.get(i);
2749 if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2750 inheritedMethods.removeByNameAndSignature(m);
2751 }
2752 }
2753 // Insert superclass's inherited methods before
2754 // superinterfaces' to satisfy getMethod's search
2755 // order
2756 supers.addAll(inheritedMethods);
2757 inheritedMethods = supers;
2758 }
2759 }
2760 // Filter out all local methods from inherited ones
2761 for (int i = 0; i < methods.length(); i++) {
2762 Method m = methods.get(i);
2763 inheritedMethods.removeByNameAndSignature(m);
2764 }
2765 methods.addAllIfNotPresent(inheritedMethods);
2766 methods.compactAndTrim();
2767 res = methods.getArray();
2768 if (rd != null) {
2769 rd.publicMethods = res;
2770 }
2771 return res;
2772 }
2773
2774
2775 //
2776 // Helpers for fetchers of one field, method, or constructor
2777 //
2778
2779 private static Field searchFields(Field[] fields, String name) {
2780 String internedName = name.intern();
2781 for (int i = 0; i < fields.length; i++) {
2782 if (fields[i].getName() == internedName) {
2783 return getReflectionFactory().copyField(fields[i]);
2784 }
2785 }
2786 return null;
2787 }
2788
2789 private Field getField0(String name) throws NoSuchFieldException {
2790 // Note: the intent is that the search algorithm this routine
2791 // uses be equivalent to the ordering imposed by
2792 // privateGetPublicFields(). It fetches only the declared
2793 // public fields for each class, however, to reduce the number
2794 // of Field objects which have to be created for the common
2795 // case where the field being requested is declared in the
2796 // class which is being queried.
2797 Field res;
2798 // Search declared public fields
2799 if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
2800 return res;
2801 }
2802 // Direct superinterfaces, recursively
2803 Class<?>[] interfaces = getInterfaces();
2804 for (int i = 0; i < interfaces.length; i++) {
2805 Class<?> c = interfaces[i];
2806 if ((res = c.getField0(name)) != null) {
2807 return res;
2808 }
2809 }
2810 // Direct superclass, recursively
2811 if (!isInterface()) {
2812 Class<?> c = getSuperclass();
2813 if (c != null) {
2814 if ((res = c.getField0(name)) != null) {
2815 return res;
2816 }
2817 }
2829 Method m = methods[i];
2830 if (m.getName() == internedName
2831 && arrayContentsEq(parameterTypes, m.getParameterTypes())
2832 && (res == null
2833 || res.getReturnType().isAssignableFrom(m.getReturnType())))
2834 res = m;
2835 }
2836
2837 return (res == null ? res : getReflectionFactory().copyMethod(res));
2838 }
2839
2840
2841 private Method getMethod0(String name, Class<?>[] parameterTypes) {
2842 // Note: the intent is that the search algorithm this routine
2843 // uses be equivalent to the ordering imposed by
2844 // privateGetPublicMethods(). It fetches only the declared
2845 // public methods for each class, however, to reduce the
2846 // number of Method objects which have to be created for the
2847 // common case where the method being requested is declared in
2848 // the class which is being queried.
2849 Method res;
2850 // Search declared public methods
2851 if ((res = searchMethods(privateGetDeclaredMethods(true),
2852 name,
2853 parameterTypes)) != null) {
2854 return res;
2855 }
2856 // Search superclass's methods
2857 if (!isInterface()) {
2858 Class<? super T> c = getSuperclass();
2859 if (c != null) {
2860 if ((res = c.getMethod0(name, parameterTypes)) != null) {
2861 return res;
2862 }
2863 }
2864 }
2865 // Search superinterfaces' methods
2866 Class<?>[] interfaces = getInterfaces();
2867 for (int i = 0; i < interfaces.length; i++) {
2868 Class<?> c = interfaces[i];
2869 if ((res = c.getMethod0(name, parameterTypes)) != null) {
3230
3231 /**
3232 * @since 1.5
3233 */
3234 public Annotation[] getAnnotations() {
3235 initAnnotationsIfNecessary();
3236 return AnnotationParser.toArray(annotations);
3237 }
3238
3239 /**
3240 * @since 1.5
3241 */
3242 public Annotation[] getDeclaredAnnotations() {
3243 initAnnotationsIfNecessary();
3244 return AnnotationParser.toArray(declaredAnnotations);
3245 }
3246
3247 // Annotations cache
3248 private transient Map<Class<? extends Annotation>, Annotation> annotations;
3249 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
3250 // Value of classRedefinedCount when we last cleared the cached annotations and declaredAnnotations fields
3251 private transient int lastAnnotationsRedefinedCount = 0;
3252
3253 // Clears cached values that might possibly have been obsoleted by
3254 // a class redefinition.
3255 private void clearAnnotationCachesOnClassRedefinition() {
3256 if (lastAnnotationsRedefinedCount != classRedefinedCount) {
3257 annotations = declaredAnnotations = null;
3258 lastAnnotationsRedefinedCount = classRedefinedCount;
3259 }
3260 }
3261
3262 private synchronized void initAnnotationsIfNecessary() {
3263 clearAnnotationCachesOnClassRedefinition();
3264 if (annotations != null)
3265 return;
3266 declaredAnnotations = AnnotationParser.parseAnnotations(
3267 getRawAnnotations(), getConstantPool(), this);
3268 Class<?> superClass = getSuperclass();
3269 if (superClass == null) {
3270 annotations = declaredAnnotations;
3271 } else {
3272 annotations = new HashMap<>();
3273 superClass.initAnnotationsIfNecessary();
3274 for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3275 Class<? extends Annotation> annotationClass = e.getKey();
3276 if (AnnotationType.getInstance(annotationClass).isInherited())
3277 annotations.put(annotationClass, e.getValue());
3278 }
3279 annotations.putAll(declaredAnnotations);
3280 }
3281 }
3282
3283 // Annotation types cache their internal (AnnotationType) form
3284
3285 @SuppressWarnings("UnusedDeclaration")
3286 private volatile transient AnnotationType annotationType;
3287
3288 boolean casAnnotationType(AnnotationType oldType, AnnotationType newType) {
3289 return Atomic.casAnnotationType(this, oldType, newType);
3290 }
3291
3292 AnnotationType getAnnotationType() {
3293 return annotationType;
3294 }
3295
3296 /* Backing store of user-defined values pertaining to this class.
3297 * Maintained by the ClassValue class.
3298 */
3299 transient ClassValue.ClassValueMap classValueMap;
3300 }
|