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
|