src/share/classes/java/lang/Class.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang

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

Print this page


   1 /*
   2  * Copyright (c) 1994, 2012, 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


2197                 c = c.getComponentType();
2198             }
2199             String baseName = c.getName();
2200             int index = baseName.lastIndexOf('.');
2201             if (index != -1) {
2202                 name = baseName.substring(0, index).replace('.', '/')
2203                     +"/"+name;
2204             }
2205         } else {
2206             name = name.substring(1);
2207         }
2208         return name;
2209     }
2210 
2211     /**
2212      * Reflection support.
2213      */
2214 
2215     // Caches for certain reflective results
2216     private static boolean useCaches = true;
2217     private volatile transient SoftReference<Field[]> declaredFields;
2218     private volatile transient SoftReference<Field[]> publicFields;
2219     private volatile transient SoftReference<Method[]> declaredMethods;
2220     private volatile transient SoftReference<Method[]> publicMethods;
2221     private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
2222     private volatile transient SoftReference<Constructor<T>[]> publicConstructors;



2223     // Intermediate results for getFields and getMethods
2224     private volatile transient SoftReference<Field[]> declaredPublicFields;
2225     private volatile transient SoftReference<Method[]> declaredPublicMethods;


2226 






























2227     // Incremented by the VM on each call to JVM TI RedefineClasses()
2228     // that redefines this class or a superclass.
2229     private volatile transient int classRedefinedCount = 0;
2230 
2231     // Value of classRedefinedCount when we last cleared the cached values
2232     // that are sensitive to class redefinition.
2233     private volatile transient int lastRedefinedCount = 0;












2234 
2235     // Clears cached values that might possibly have been obsoleted by
2236     // a class redefinition.
2237     private void clearCachesOnClassRedefinition() {
2238         if (lastRedefinedCount != classRedefinedCount) {
2239             declaredFields = publicFields = declaredPublicFields = null;
2240             declaredMethods = publicMethods = declaredPublicMethods = null;
2241             declaredConstructors = publicConstructors = null;
2242             annotations = declaredAnnotations = null;
2243 
2244             // Use of "volatile" (and synchronization by caller in the case
2245             // of annotations) ensures that no thread sees the update to
2246             // lastRedefinedCount before seeing the caches cleared.
2247             // We do not guard against brief windows during which multiple
2248             // threads might redundantly work to fill an empty cache.
2249             lastRedefinedCount = classRedefinedCount;
2250         }







2251     }


2252 
2253     // Generic signature handling
2254     private native String getGenericSignature();
2255 
2256     // Generic info repository; lazily initialized
2257     private transient ClassRepository genericInfo;
2258 
2259     // accessor for factory
2260     private GenericsFactory getFactory() {
2261         // create scope and factory
2262         return CoreReflectionFactory.make(this, ClassScope.make(this));
2263     }
2264 
2265     // accessor for generic info repository
2266     private ClassRepository getGenericInfo() {
2267         // lazily initialize repository if necessary
2268         if (genericInfo == null) {
2269             // create and cache generic info repository
2270             genericInfo = ClassRepository.make(getGenericSignature(),
2271                                                getFactory());
2272         }
2273         return genericInfo; //return cached repository
2274     }
2275 
2276     // Annotations handling
2277     private native byte[] getRawAnnotations();
2278 
2279     native ConstantPool getConstantPool();
2280 
2281     //
2282     //
2283     // java.lang.reflect.Field handling
2284     //
2285     //
2286 
2287     // Returns an array of "root" fields. These Field objects must NOT
2288     // be propagated to the outside world, but must instead be copied
2289     // via ReflectionFactory.copyField.
2290     private Field[] privateGetDeclaredFields(boolean publicOnly) {
2291         checkInitted();
2292         Field[] res = null;
2293         if (useCaches) {
2294             clearCachesOnClassRedefinition();
2295             if (publicOnly) {
2296                 if (declaredPublicFields != null) {
2297                     res = declaredPublicFields.get();
2298                 }
2299             } else {
2300                 if (declaredFields != null) {
2301                     res = declaredFields.get();
2302                 }
2303             }
2304             if (res != null) return res;
2305         }
2306         // No cached value available; request value from VM
2307         res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2308         if (useCaches) {
2309             if (publicOnly) {
2310                 declaredPublicFields = new SoftReference<>(res);
2311             } else {
2312                 declaredFields = new SoftReference<>(res);
2313             }
2314         }
2315         return res;
2316     }
2317 
2318     // Returns an array of "root" fields. These Field objects must NOT
2319     // be propagated to the outside world, but must instead be copied
2320     // via ReflectionFactory.copyField.
2321     private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2322         checkInitted();
2323         Field[] res = null;
2324         if (useCaches) {
2325             clearCachesOnClassRedefinition();
2326             if (publicFields != null) {
2327                 res = publicFields.get();
2328             }
2329             if (res != null) return res;
2330         }
2331 
2332         // No cached value available; compute value recursively.
2333         // Traverse in correct order for getField().
2334         List<Field> fields = new ArrayList<>();
2335         if (traversedInterfaces == null) {
2336             traversedInterfaces = new HashSet<>();
2337         }
2338 
2339         // Local fields
2340         Field[] tmp = privateGetDeclaredFields(true);
2341         addAll(fields, tmp);
2342 
2343         // Direct superinterfaces, recursively
2344         for (Class<?> c : getInterfaces()) {
2345             if (!traversedInterfaces.contains(c)) {
2346                 traversedInterfaces.add(c);
2347                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2348             }
2349         }
2350 
2351         // Direct superclass, recursively
2352         if (!isInterface()) {
2353             Class<?> c = getSuperclass();
2354             if (c != null) {
2355                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2356             }
2357         }
2358 
2359         res = new Field[fields.size()];
2360         fields.toArray(res);
2361         if (useCaches) {
2362             publicFields = new SoftReference<>(res);
2363         }
2364         return res;
2365     }
2366 
2367     private static void addAll(Collection<Field> c, Field[] o) {
2368         for (int i = 0; i < o.length; i++) {
2369             c.add(o[i]);
2370         }
2371     }
2372 
2373 
2374     //
2375     //
2376     // java.lang.reflect.Constructor handling
2377     //
2378     //
2379 
2380     // Returns an array of "root" constructors. These Constructor
2381     // objects must NOT be propagated to the outside world, but must
2382     // instead be copied via ReflectionFactory.copyConstructor.
2383     private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
2384         checkInitted();
2385         Constructor<T>[] res = null;
2386         if (useCaches) {
2387             clearCachesOnClassRedefinition();
2388             if (publicOnly) {
2389                 if (publicConstructors != null) {
2390                     res = publicConstructors.get();
2391                 }
2392             } else {
2393                 if (declaredConstructors != null) {
2394                     res = declaredConstructors.get();
2395                 }
2396             }
2397             if (res != null) return res;
2398         }
2399         // No cached value available; request value from VM
2400         if (isInterface()) {
2401             @SuppressWarnings("unchecked")
2402             Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
2403             res = temporaryRes;
2404         } else {
2405             res = getDeclaredConstructors0(publicOnly);
2406         }
2407         if (useCaches) {
2408             if (publicOnly) {
2409                 publicConstructors = new SoftReference<>(res);
2410             } else {
2411                 declaredConstructors = new SoftReference<>(res);
2412             }
2413         }
2414         return res;
2415     }
2416 
2417     //
2418     //
2419     // java.lang.reflect.Method handling
2420     //
2421     //
2422 
2423     // Returns an array of "root" methods. These Method objects must NOT
2424     // be propagated to the outside world, but must instead be copied
2425     // via ReflectionFactory.copyMethod.
2426     private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2427         checkInitted();
2428         Method[] res = null;
2429         if (useCaches) {
2430             clearCachesOnClassRedefinition();
2431             if (publicOnly) {
2432                 if (declaredPublicMethods != null) {
2433                     res = declaredPublicMethods.get();
2434                 }
2435             } else {
2436                 if (declaredMethods != null) {
2437                     res = declaredMethods.get();
2438                 }
2439             }
2440             if (res != null) return res;
2441         }
2442         // No cached value available; request value from VM
2443         res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2444         if (useCaches) {
2445             if (publicOnly) {
2446                 declaredPublicMethods = new SoftReference<>(res);
2447             } else {
2448                 declaredMethods = new SoftReference<>(res);
2449             }
2450         }
2451         return res;
2452     }
2453 
2454     static class MethodArray {
2455         private Method[] methods;
2456         private int length;
2457 
2458         MethodArray() {
2459             methods = new Method[20];
2460             length = 0;
2461         }
2462 
2463         void add(Method m) {
2464             if (length == methods.length) {
2465                 methods = Arrays.copyOf(methods, 2 * methods.length);
2466             }
2467             methods[length++] = m;
2468         }


2530                     }
2531                     newPos++;
2532                 }
2533             }
2534             if (newPos != methods.length) {
2535                 methods = Arrays.copyOf(methods, newPos);
2536             }
2537         }
2538 
2539         Method[] getArray() {
2540             return methods;
2541         }
2542     }
2543 
2544 
2545     // Returns an array of "root" methods. These Method objects must NOT
2546     // be propagated to the outside world, but must instead be copied
2547     // via ReflectionFactory.copyMethod.
2548     private Method[] privateGetPublicMethods() {
2549         checkInitted();
2550         Method[] res = null;
2551         if (useCaches) {
2552             clearCachesOnClassRedefinition();
2553             if (publicMethods != null) {
2554                 res = publicMethods.get();
2555             }
2556             if (res != null) return res;
2557         }
2558 
2559         // No cached value available; compute value recursively.
2560         // Start by fetching public declared methods
2561         MethodArray methods = new MethodArray();
2562         {
2563                 Method[] tmp = privateGetDeclaredMethods(true);
2564             methods.addAll(tmp);
2565         }
2566         // Now recur over superclass and direct superinterfaces.
2567         // Go over superinterfaces first so we can more easily filter
2568         // out concrete implementations inherited from superclasses at
2569         // the end.
2570         MethodArray inheritedMethods = new MethodArray();
2571         Class<?>[] interfaces = getInterfaces();
2572         for (int i = 0; i < interfaces.length; i++) {
2573             inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
2574         }
2575         if (!isInterface()) {


2583                     Method m = supers.get(i);
2584                     if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2585                         inheritedMethods.removeByNameAndSignature(m);
2586                     }
2587                 }
2588                 // Insert superclass's inherited methods before
2589                 // superinterfaces' to satisfy getMethod's search
2590                 // order
2591                 supers.addAll(inheritedMethods);
2592                 inheritedMethods = supers;
2593             }
2594         }
2595         // Filter out all local methods from inherited ones
2596         for (int i = 0; i < methods.length(); i++) {
2597             Method m = methods.get(i);
2598             inheritedMethods.removeByNameAndSignature(m);
2599         }
2600         methods.addAllIfNotPresent(inheritedMethods);
2601         methods.compactAndTrim();
2602         res = methods.getArray();
2603         if (useCaches) {
2604             publicMethods = new SoftReference<>(res);
2605         }
2606         return res;
2607     }
2608 
2609 
2610     //
2611     // Helpers for fetchers of one field, method, or constructor
2612     //
2613 
2614     private Field searchFields(Field[] fields, String name) {
2615         String internedName = name.intern();
2616         for (int i = 0; i < fields.length; i++) {
2617             if (fields[i].getName() == internedName) {
2618                 return getReflectionFactory().copyField(fields[i]);
2619             }
2620         }
2621         return null;
2622     }
2623 
2624     private Field getField0(String name) throws NoSuchFieldException {
2625         // Note: the intent is that the search algorithm this routine
2626         // uses be equivalent to the ordering imposed by
2627         // privateGetPublicFields(). It fetches only the declared
2628         // public fields for each class, however, to reduce the number
2629         // of Field objects which have to be created for the common
2630         // case where the field being requested is declared in the
2631         // class which is being queried.
2632         Field res = null;
2633         // Search declared public fields
2634         if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
2635             return res;
2636         }
2637         // Direct superinterfaces, recursively
2638         Class<?>[] interfaces = getInterfaces();
2639         for (int i = 0; i < interfaces.length; i++) {
2640             Class<?> c = interfaces[i];
2641             if ((res = c.getField0(name)) != null) {
2642                 return res;
2643             }
2644         }
2645         // Direct superclass, recursively
2646         if (!isInterface()) {
2647             Class<?> c = getSuperclass();
2648             if (c != null) {
2649                 if ((res = c.getField0(name)) != null) {
2650                     return res;
2651                 }
2652             }


2664             Method m = methods[i];
2665             if (m.getName() == internedName
2666                 && arrayContentsEq(parameterTypes, m.getParameterTypes())
2667                 && (res == null
2668                     || res.getReturnType().isAssignableFrom(m.getReturnType())))
2669                 res = m;
2670         }
2671 
2672         return (res == null ? res : getReflectionFactory().copyMethod(res));
2673     }
2674 
2675 
2676     private Method getMethod0(String name, Class<?>[] parameterTypes) {
2677         // Note: the intent is that the search algorithm this routine
2678         // uses be equivalent to the ordering imposed by
2679         // privateGetPublicMethods(). It fetches only the declared
2680         // public methods for each class, however, to reduce the
2681         // number of Method objects which have to be created for the
2682         // common case where the method being requested is declared in
2683         // the class which is being queried.
2684         Method res = null;
2685         // Search declared public methods
2686         if ((res = searchMethods(privateGetDeclaredMethods(true),
2687                                  name,
2688                                  parameterTypes)) != null) {
2689             return res;
2690         }
2691         // Search superclass's methods
2692         if (!isInterface()) {
2693             Class<? super T> c = getSuperclass();
2694             if (c != null) {
2695                 if ((res = c.getMethod0(name, parameterTypes)) != null) {
2696                     return res;
2697                 }
2698             }
2699         }
2700         // Search superinterfaces' methods
2701         Class<?>[] interfaces = getInterfaces();
2702         for (int i = 0; i < interfaces.length; i++) {
2703             Class<?> c = interfaces[i];
2704             if ((res = c.getMethod0(name, parameterTypes)) != null) {


3108      * @since 1.5
3109      */
3110     public Annotation[] getDeclaredAnnotations()  {
3111         initAnnotationsIfNecessary();
3112         return AnnotationSupport.unpackToArray(declaredAnnotations);
3113     }
3114 
3115     /** Returns one "directly" present annotation or null */
3116     <A extends Annotation> A getDirectDeclaredAnnotation(Class<A> annotationClass) {
3117         Objects.requireNonNull(annotationClass);
3118 
3119         initAnnotationsIfNecessary();
3120         @SuppressWarnings("unchecked") // TODO check safe
3121         A ret = (A)declaredAnnotations.get(annotationClass);
3122         return ret;
3123     }
3124 
3125     // Annotations cache
3126     private transient Map<Class<? extends Annotation>, Annotation> annotations;
3127     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;


3128 









3129     private synchronized void initAnnotationsIfNecessary() {
3130         clearCachesOnClassRedefinition();
3131         if (annotations != null)
3132             return;
3133         declaredAnnotations = AnnotationParser.parseAnnotations(
3134             getRawAnnotations(), getConstantPool(), this);
3135         Class<?> superClass = getSuperclass();
3136         if (superClass == null) {
3137             annotations = declaredAnnotations;
3138         } else {
3139             annotations = new HashMap<>();
3140             superClass.initAnnotationsIfNecessary();
3141             for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3142                 Class<? extends Annotation> annotationClass = e.getKey();
3143                 if (AnnotationType.getInstance(annotationClass).isInherited())
3144                     annotations.put(annotationClass, e.getValue());
3145             }
3146             annotations.putAll(declaredAnnotations);
3147         }
3148     }
3149 
3150     // Annotation types cache their internal (AnnotationType) form
   1 /*
   2  * Copyright (c) 1994, 2013, 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


2197                 c = c.getComponentType();
2198             }
2199             String baseName = c.getName();
2200             int index = baseName.lastIndexOf('.');
2201             if (index != -1) {
2202                 name = baseName.substring(0, index).replace('.', '/')
2203                     +"/"+name;
2204             }
2205         } else {
2206             name = name.substring(1);
2207         }
2208         return name;
2209     }
2210 
2211     /**
2212      * Reflection support.
2213      */
2214 
2215     // Caches for certain reflective results
2216     private static boolean useCaches = true;
2217 
2218     // reflection data that might get invalidated when JVM TI RedefineClasses() is called
2219     static class ReflectionData<T> {
2220         volatile Field[] declaredFields;
2221         volatile Field[] publicFields;
2222         volatile Method[] declaredMethods;
2223         volatile Method[] publicMethods;
2224         volatile Constructor<T>[] declaredConstructors;
2225         volatile Constructor<T>[] publicConstructors;
2226         // Intermediate results for getFields and getMethods
2227         volatile Field[] declaredPublicFields;
2228         volatile Method[] declaredPublicMethods;
2229         // Value of classRedefinedCount when we created this ReflectionData instance
2230         final int redefinedCount;
2231 
2232         ReflectionData(int redefinedCount) {
2233             this.redefinedCount = redefinedCount;
2234         }
2235 
2236         // initialize Unsafe machinery here, since we need to call Class.class instance method
2237         // and have to avoid calling it in the static initializer of the Class class...
2238         private static final Unsafe unsafe;
2239         // offset of Class.reflectionData instance field
2240         private static final long reflectionDataOffset;
2241 
2242         static {
2243             unsafe = Unsafe.getUnsafe();
2244             // bypass caches
2245             Field reflectionDataField = searchFields(Class.class.getDeclaredFields0(false),
2246                                                      "reflectionData");
2247             if (reflectionDataField == null) {
2248                 throw new Error("No reflectionData field found in java.lang.Class");
2249             }
2250             reflectionDataOffset = unsafe.objectFieldOffset(reflectionDataField);
2251         }
2252 
2253         static <T> boolean compareAndSwap(Class<?> clazz,
2254                                           SoftReference<ReflectionData<T>> oldData,
2255                                           SoftReference<ReflectionData<T>> newData) {
2256             return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
2257         }
2258     }
2259     
2260     private volatile transient SoftReference<ReflectionData<T>> reflectionData;
2261 
2262     // Incremented by the VM on each call to JVM TI RedefineClasses()
2263     // that redefines this class or a superclass.
2264     private volatile transient int classRedefinedCount = 0;
2265 
2266     // Lazily create and cache ReflectionData
2267     private ReflectionData<T> reflectionData() {
2268         SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2269         int classRedefinedCount = this.classRedefinedCount;
2270         ReflectionData<T> rd;
2271         if (useCaches &&
2272             reflectionData != null &&
2273             (rd = reflectionData.get()) != null &&
2274             rd.redefinedCount == classRedefinedCount) {
2275             return rd;
2276         }
2277         // else no SoftReference or cleared SoftReference or stale ReflectionData
2278         // -> create and replace new instance
2279         return newReflectionData(reflectionData, classRedefinedCount);
2280     }
2281 
2282     private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
2283                                                 int classRedefinedCount) {
2284         if (!useCaches) return null;





2285 
2286         while (true) {
2287             ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2288             // try to CAS it...
2289             if (ReflectionData.compareAndSwap(this, oldReflectionData, new SoftReference<>(rd))) {
2290                 return rd;

2291             }
2292             // else retry
2293             oldReflectionData = this.reflectionData;
2294             classRedefinedCount = this.classRedefinedCount;
2295             if (oldReflectionData != null &&
2296                 (rd = oldReflectionData.get()) != null &&
2297                 rd.redefinedCount == classRedefinedCount) {
2298                 return rd;
2299             }
2300         }
2301     }
2302 
2303     // Generic signature handling
2304     private native String getGenericSignature();
2305 
2306     // Generic info repository; lazily initialized
2307     private transient ClassRepository genericInfo;
2308 
2309     // accessor for factory
2310     private GenericsFactory getFactory() {
2311         // create scope and factory
2312         return CoreReflectionFactory.make(this, ClassScope.make(this));
2313     }
2314 
2315     // accessor for generic info repository
2316     private ClassRepository getGenericInfo() {
2317         // lazily initialize repository if necessary
2318         if (genericInfo == null) {
2319             // create and cache generic info repository
2320             genericInfo = ClassRepository.make(getGenericSignature(),
2321                                                getFactory());
2322         }
2323         return genericInfo; //return cached repository
2324     }
2325 
2326     // Annotations handling
2327     private native byte[] getRawAnnotations();
2328 
2329     native ConstantPool getConstantPool();
2330 
2331     //
2332     //
2333     // java.lang.reflect.Field handling
2334     //
2335     //
2336 
2337     // Returns an array of "root" fields. These Field objects must NOT
2338     // be propagated to the outside world, but must instead be copied
2339     // via ReflectionFactory.copyField.
2340     private Field[] privateGetDeclaredFields(boolean publicOnly) {
2341         checkInitted();
2342         Field[] res;
2343         ReflectionData<T> rd = reflectionData();
2344         if (rd != null) {
2345             res = publicOnly ? rd.declaredPublicFields : rd.declaredFields;








2346             if (res != null) return res;
2347         }
2348         // No cached value available; request value from VM
2349         res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2350         if (rd != null) {
2351             if (publicOnly) {
2352                 rd.declaredPublicFields = res;
2353             } else {
2354                 rd.declaredFields = res;
2355             }
2356         }
2357         return res;
2358     }
2359 
2360     // Returns an array of "root" fields. These Field objects must NOT
2361     // be propagated to the outside world, but must instead be copied
2362     // via ReflectionFactory.copyField.
2363     private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2364         checkInitted();
2365         Field[] res;
2366         ReflectionData<T> rd = reflectionData();
2367         if (rd != null) {
2368             res = rd.publicFields;


2369             if (res != null) return res;
2370         }
2371 
2372         // No cached value available; compute value recursively.
2373         // Traverse in correct order for getField().
2374         List<Field> fields = new ArrayList<>();
2375         if (traversedInterfaces == null) {
2376             traversedInterfaces = new HashSet<>();
2377         }
2378 
2379         // Local fields
2380         Field[] tmp = privateGetDeclaredFields(true);
2381         addAll(fields, tmp);
2382 
2383         // Direct superinterfaces, recursively
2384         for (Class<?> c : getInterfaces()) {
2385             if (!traversedInterfaces.contains(c)) {
2386                 traversedInterfaces.add(c);
2387                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2388             }
2389         }
2390 
2391         // Direct superclass, recursively
2392         if (!isInterface()) {
2393             Class<?> c = getSuperclass();
2394             if (c != null) {
2395                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2396             }
2397         }
2398 
2399         res = new Field[fields.size()];
2400         fields.toArray(res);
2401         if (rd != null) {
2402             rd.publicFields = res;
2403         }
2404         return res;
2405     }
2406 
2407     private static void addAll(Collection<Field> c, Field[] o) {
2408         for (int i = 0; i < o.length; i++) {
2409             c.add(o[i]);
2410         }
2411     }
2412 
2413 
2414     //
2415     //
2416     // java.lang.reflect.Constructor handling
2417     //
2418     //
2419 
2420     // Returns an array of "root" constructors. These Constructor
2421     // objects must NOT be propagated to the outside world, but must
2422     // instead be copied via ReflectionFactory.copyConstructor.
2423     private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
2424         checkInitted();
2425         Constructor<T>[] res;
2426         ReflectionData<T> rd = reflectionData();
2427         if (rd != null) {
2428             res = publicOnly ? rd.publicConstructors : rd.declaredConstructors;








2429             if (res != null) return res;
2430         }
2431         // No cached value available; request value from VM
2432         if (isInterface()) {
2433             @SuppressWarnings("unchecked")
2434             Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
2435             res = temporaryRes;
2436         } else {
2437             res = getDeclaredConstructors0(publicOnly);
2438         }
2439         if (rd != null) {
2440             if (publicOnly) {
2441                 rd.publicConstructors = res;
2442             } else {
2443                 rd.declaredConstructors = res;
2444             }
2445         }
2446         return res;
2447     }
2448 
2449     //
2450     //
2451     // java.lang.reflect.Method handling
2452     //
2453     //
2454 
2455     // Returns an array of "root" methods. These Method objects must NOT
2456     // be propagated to the outside world, but must instead be copied
2457     // via ReflectionFactory.copyMethod.
2458     private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2459         checkInitted();
2460         Method[] res;
2461         ReflectionData<T> rd = reflectionData();
2462         if (rd != null) {
2463             res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;








2464             if (res != null) return res;
2465         }
2466         // No cached value available; request value from VM
2467         res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2468         if (rd != null) {
2469             if (publicOnly) {
2470                 rd.declaredPublicMethods = res;
2471             } else {
2472                 rd.declaredMethods = res;
2473             }
2474         }
2475         return res;
2476     }
2477 
2478     static class MethodArray {
2479         private Method[] methods;
2480         private int length;
2481 
2482         MethodArray() {
2483             methods = new Method[20];
2484             length = 0;
2485         }
2486 
2487         void add(Method m) {
2488             if (length == methods.length) {
2489                 methods = Arrays.copyOf(methods, 2 * methods.length);
2490             }
2491             methods[length++] = m;
2492         }


2554                     }
2555                     newPos++;
2556                 }
2557             }
2558             if (newPos != methods.length) {
2559                 methods = Arrays.copyOf(methods, newPos);
2560             }
2561         }
2562 
2563         Method[] getArray() {
2564             return methods;
2565         }
2566     }
2567 
2568 
2569     // Returns an array of "root" methods. These Method objects must NOT
2570     // be propagated to the outside world, but must instead be copied
2571     // via ReflectionFactory.copyMethod.
2572     private Method[] privateGetPublicMethods() {
2573         checkInitted();
2574         Method[] res;
2575         ReflectionData<T> rd = reflectionData();
2576         if (rd != null) {
2577             res = rd.publicMethods;


2578             if (res != null) return res;
2579         }
2580 
2581         // No cached value available; compute value recursively.
2582         // Start by fetching public declared methods
2583         MethodArray methods = new MethodArray();
2584         {
2585             Method[] tmp = privateGetDeclaredMethods(true);
2586             methods.addAll(tmp);
2587         }
2588         // Now recur over superclass and direct superinterfaces.
2589         // Go over superinterfaces first so we can more easily filter
2590         // out concrete implementations inherited from superclasses at
2591         // the end.
2592         MethodArray inheritedMethods = new MethodArray();
2593         Class<?>[] interfaces = getInterfaces();
2594         for (int i = 0; i < interfaces.length; i++) {
2595             inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
2596         }
2597         if (!isInterface()) {


2605                     Method m = supers.get(i);
2606                     if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2607                         inheritedMethods.removeByNameAndSignature(m);
2608                     }
2609                 }
2610                 // Insert superclass's inherited methods before
2611                 // superinterfaces' to satisfy getMethod's search
2612                 // order
2613                 supers.addAll(inheritedMethods);
2614                 inheritedMethods = supers;
2615             }
2616         }
2617         // Filter out all local methods from inherited ones
2618         for (int i = 0; i < methods.length(); i++) {
2619             Method m = methods.get(i);
2620             inheritedMethods.removeByNameAndSignature(m);
2621         }
2622         methods.addAllIfNotPresent(inheritedMethods);
2623         methods.compactAndTrim();
2624         res = methods.getArray();
2625         if (rd != null) {
2626             rd.publicMethods = res;
2627         }
2628         return res;
2629     }
2630 
2631 
2632     //
2633     // Helpers for fetchers of one field, method, or constructor
2634     //
2635 
2636     private static Field searchFields(Field[] fields, String name) {
2637         String internedName = name.intern();
2638         for (int i = 0; i < fields.length; i++) {
2639             if (fields[i].getName() == internedName) {
2640                 return getReflectionFactory().copyField(fields[i]);
2641             }
2642         }
2643         return null;
2644     }
2645 
2646     private Field getField0(String name) throws NoSuchFieldException {
2647         // Note: the intent is that the search algorithm this routine
2648         // uses be equivalent to the ordering imposed by
2649         // privateGetPublicFields(). It fetches only the declared
2650         // public fields for each class, however, to reduce the number
2651         // of Field objects which have to be created for the common
2652         // case where the field being requested is declared in the
2653         // class which is being queried.
2654         Field res;
2655         // Search declared public fields
2656         if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
2657             return res;
2658         }
2659         // Direct superinterfaces, recursively
2660         Class<?>[] interfaces = getInterfaces();
2661         for (int i = 0; i < interfaces.length; i++) {
2662             Class<?> c = interfaces[i];
2663             if ((res = c.getField0(name)) != null) {
2664                 return res;
2665             }
2666         }
2667         // Direct superclass, recursively
2668         if (!isInterface()) {
2669             Class<?> c = getSuperclass();
2670             if (c != null) {
2671                 if ((res = c.getField0(name)) != null) {
2672                     return res;
2673                 }
2674             }


2686             Method m = methods[i];
2687             if (m.getName() == internedName
2688                 && arrayContentsEq(parameterTypes, m.getParameterTypes())
2689                 && (res == null
2690                     || res.getReturnType().isAssignableFrom(m.getReturnType())))
2691                 res = m;
2692         }
2693 
2694         return (res == null ? res : getReflectionFactory().copyMethod(res));
2695     }
2696 
2697 
2698     private Method getMethod0(String name, Class<?>[] parameterTypes) {
2699         // Note: the intent is that the search algorithm this routine
2700         // uses be equivalent to the ordering imposed by
2701         // privateGetPublicMethods(). It fetches only the declared
2702         // public methods for each class, however, to reduce the
2703         // number of Method objects which have to be created for the
2704         // common case where the method being requested is declared in
2705         // the class which is being queried.
2706         Method res;
2707         // Search declared public methods
2708         if ((res = searchMethods(privateGetDeclaredMethods(true),
2709                                  name,
2710                                  parameterTypes)) != null) {
2711             return res;
2712         }
2713         // Search superclass's methods
2714         if (!isInterface()) {
2715             Class<? super T> c = getSuperclass();
2716             if (c != null) {
2717                 if ((res = c.getMethod0(name, parameterTypes)) != null) {
2718                     return res;
2719                 }
2720             }
2721         }
2722         // Search superinterfaces' methods
2723         Class<?>[] interfaces = getInterfaces();
2724         for (int i = 0; i < interfaces.length; i++) {
2725             Class<?> c = interfaces[i];
2726             if ((res = c.getMethod0(name, parameterTypes)) != null) {


3130      * @since 1.5
3131      */
3132     public Annotation[] getDeclaredAnnotations()  {
3133         initAnnotationsIfNecessary();
3134         return AnnotationSupport.unpackToArray(declaredAnnotations);
3135     }
3136 
3137     /** Returns one "directly" present annotation or null */
3138     <A extends Annotation> A getDirectDeclaredAnnotation(Class<A> annotationClass) {
3139         Objects.requireNonNull(annotationClass);
3140 
3141         initAnnotationsIfNecessary();
3142         @SuppressWarnings("unchecked") // TODO check safe
3143         A ret = (A)declaredAnnotations.get(annotationClass);
3144         return ret;
3145     }
3146 
3147     // Annotations cache
3148     private transient Map<Class<? extends Annotation>, Annotation> annotations;
3149     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
3150     // Value of classRedefinedCount when we last cleared the cached annotations and declaredAnnotations fields
3151     private  transient int lastAnnotationsRedefinedCount = 0;
3152 
3153     // Clears cached values that might possibly have been obsoleted by
3154     // a class redefinition.
3155     private void clearAnnotationCachesOnClassRedefinition() {
3156         if (lastAnnotationsRedefinedCount != classRedefinedCount) {
3157             annotations = declaredAnnotations = null;
3158             lastAnnotationsRedefinedCount = classRedefinedCount;
3159         }
3160     }
3161 
3162     private synchronized void initAnnotationsIfNecessary() {
3163         clearAnnotationCachesOnClassRedefinition();
3164         if (annotations != null)
3165             return;
3166         declaredAnnotations = AnnotationParser.parseAnnotations(
3167             getRawAnnotations(), getConstantPool(), this);
3168         Class<?> superClass = getSuperclass();
3169         if (superClass == null) {
3170             annotations = declaredAnnotations;
3171         } else {
3172             annotations = new HashMap<>();
3173             superClass.initAnnotationsIfNecessary();
3174             for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3175                 Class<? extends Annotation> annotationClass = e.getKey();
3176                 if (AnnotationType.getInstance(annotationClass).isInherited())
3177                     annotations.put(annotationClass, e.getValue());
3178             }
3179             annotations.putAll(declaredAnnotations);
3180         }
3181     }
3182 
3183     // Annotation types cache their internal (AnnotationType) form
src/share/classes/java/lang/Class.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File