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

Print this page


   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 }