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
310 *
311 * </ul>
312 *
313 */
314 public T newInstance()
315 throws InstantiationException, IllegalAccessException
316 {
317 if (System.getSecurityManager() != null) {
318 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
319 }
320 return newInstance0();
321 }
322
323 private T newInstance0()
324 throws InstantiationException, IllegalAccessException
325 {
326 // NOTE: the following code may not be strictly correct under
327 // the current Java memory model.
328
329 // Constructor lookup
330 if (cachedConstructor == null) {
331 if (this == Class.class) {
332 throw new IllegalAccessException(
333 "Can not call newInstance() on the Class for java.lang.Class"
334 );
335 }
336 try {
337 Class<?>[] empty = {};
338 final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
339 // Disable accessibility checks on the constructor
340 // since we have to do the security check here anyway
341 // (the stack depth is wrong for the Constructor's
342 // security check to work)
343 java.security.AccessController.doPrivileged(
344 new java.security.PrivilegedAction<Void>() {
345 public Void run() {
346 c.setAccessible(true);
347 return null;
348 }
349 });
350 cachedConstructor = c;
351 } catch (NoSuchMethodException e) {
352 throw (InstantiationException)
353 new InstantiationException(getName()).initCause(e);
354 }
355 }
356 Constructor<T> tmpConstructor = cachedConstructor;
357 // Security check (same as in java.lang.reflect.Constructor)
358 int modifiers = tmpConstructor.getModifiers();
359 if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
360 Class<?> caller = Reflection.getCallerClass(3);
361 if (newInstanceCallerCache != caller) {
362 Reflection.ensureMemberAccess(caller, this, null, modifiers);
363 newInstanceCallerCache = caller;
364 }
365 }
366 // Run constructor
367 try {
368 return tmpConstructor.newInstance((Object[])null);
369 } catch (InvocationTargetException e) {
370 Unsafe.getUnsafe().throwException(e.getTargetException());
371 // Not reached
372 return null;
373 }
374 }
375 private volatile transient Constructor<T> cachedConstructor;
376 private volatile transient Class<?> newInstanceCallerCache;
377
378
379 /**
380 * Determines if the specified {@code Object} is assignment-compatible
381 * with the object represented by this {@code Class}. This method is
382 * the dynamic equivalent of the Java language {@code instanceof}
383 * operator. The method returns {@code true} if the specified
384 * {@code Object} argument is non-null and can be cast to the
385 * reference type represented by this {@code Class} object without
386 * raising a {@code ClassCastException.} It returns {@code false}
387 * otherwise.
388 *
389 * <p> Specifically, if this {@code Class} object represents a
390 * declared class, this method returns {@code true} if the specified
391 * {@code Object} argument is an instance of the represented class (or
392 * of any of its subclasses); it returns {@code false} otherwise. If
393 * this {@code Class} object represents an array class, this method
394 * returns {@code true} if the specified {@code Object} argument
395 * can be converted to an object of the array class by an identity
396 * conversion or by a widening reference conversion; it returns
2193 Class<?> c = this;
2194 while (c.isArray()) {
2195 c = c.getComponentType();
2196 }
2197 String baseName = c.getName();
2198 int index = baseName.lastIndexOf('.');
2199 if (index != -1) {
2200 name = baseName.substring(0, index).replace('.', '/')
2201 +"/"+name;
2202 }
2203 } else {
2204 name = name.substring(1);
2205 }
2206 return name;
2207 }
2208
2209 /**
2210 * Reflection support.
2211 */
2212
2213 // Caches for certain reflective results
2214 private static boolean useCaches = true;
2215 private volatile transient SoftReference<Field[]> declaredFields;
2216 private volatile transient SoftReference<Field[]> publicFields;
2217 private volatile transient SoftReference<Method[]> declaredMethods;
2218 private volatile transient SoftReference<Method[]> publicMethods;
2219 private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
2220 private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
2221 // Intermediate results for getFields and getMethods
2222 private volatile transient SoftReference<Field[]> declaredPublicFields;
2223 private volatile transient SoftReference<Method[]> declaredPublicMethods;
2224
2225 // Incremented by the VM on each call to JVM TI RedefineClasses()
2226 // that redefines this class or a superclass.
2227 private volatile transient int classRedefinedCount = 0;
2228
2229 // Value of classRedefinedCount when we last cleared the cached values
2230 // that are sensitive to class redefinition.
2231 private volatile transient int lastRedefinedCount = 0;
2232
2233 // Clears cached values that might possibly have been obsoleted by
2234 // a class redefinition.
2235 private void clearCachesOnClassRedefinition() {
2236 if (lastRedefinedCount != classRedefinedCount) {
2237 declaredFields = publicFields = declaredPublicFields = null;
2238 declaredMethods = publicMethods = declaredPublicMethods = null;
2239 declaredConstructors = publicConstructors = null;
2240 annotations = declaredAnnotations = null;
2241
2242 // Use of "volatile" (and synchronization by caller in the case
2243 // of annotations) ensures that no thread sees the update to
2244 // lastRedefinedCount before seeing the caches cleared.
2245 // We do not guard against brief windows during which multiple
2246 // threads might redundantly work to fill an empty cache.
2247 lastRedefinedCount = classRedefinedCount;
2248 }
2249 }
2250
2251 // Generic signature handling
2252 private native String getGenericSignature();
2253
2254 // Generic info repository; lazily initialized
2255 private transient ClassRepository genericInfo;
2256
2257 // accessor for factory
2258 private GenericsFactory getFactory() {
2259 // create scope and factory
2271 return genericInfo; //return cached repository
2272 }
2273
2274 // Annotations handling
2275 private native byte[] getRawAnnotations();
2276
2277 native ConstantPool getConstantPool();
2278
2279 //
2280 //
2281 // java.lang.reflect.Field handling
2282 //
2283 //
2284
2285 // Returns an array of "root" fields. These Field objects must NOT
2286 // be propagated to the outside world, but must instead be copied
2287 // via ReflectionFactory.copyField.
2288 private Field[] privateGetDeclaredFields(boolean publicOnly) {
2289 checkInitted();
2290 Field[] res = null;
2291 if (useCaches) {
2292 clearCachesOnClassRedefinition();
2293 if (publicOnly) {
2294 if (declaredPublicFields != null) {
2295 res = declaredPublicFields.get();
2296 }
2297 } else {
2298 if (declaredFields != null) {
2299 res = declaredFields.get();
2300 }
2301 }
2302 if (res != null) return res;
2303 }
2304 // No cached value available; request value from VM
2305 res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2306 if (useCaches) {
2307 if (publicOnly) {
2308 declaredPublicFields = new SoftReference<>(res);
2309 } else {
2310 declaredFields = new SoftReference<>(res);
2311 }
2312 }
2313 return res;
2314 }
2315
2316 // Returns an array of "root" fields. These Field objects must NOT
2317 // be propagated to the outside world, but must instead be copied
2318 // via ReflectionFactory.copyField.
2319 private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2320 checkInitted();
2321 Field[] res = null;
2322 if (useCaches) {
2323 clearCachesOnClassRedefinition();
2324 if (publicFields != null) {
2325 res = publicFields.get();
2326 }
2327 if (res != null) return res;
2328 }
2329
2330 // No cached value available; compute value recursively.
2331 // Traverse in correct order for getField().
2332 List<Field> fields = new ArrayList<>();
2333 if (traversedInterfaces == null) {
2334 traversedInterfaces = new HashSet<>();
2335 }
2336
2337 // Local fields
2338 Field[] tmp = privateGetDeclaredFields(true);
2339 addAll(fields, tmp);
2340
2341 // Direct superinterfaces, recursively
2342 for (Class<?> c : getInterfaces()) {
2343 if (!traversedInterfaces.contains(c)) {
2344 traversedInterfaces.add(c);
2345 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2346 }
2347 }
2348
2349 // Direct superclass, recursively
2350 if (!isInterface()) {
2351 Class<?> c = getSuperclass();
2352 if (c != null) {
2353 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2354 }
2355 }
2356
2357 res = new Field[fields.size()];
2358 fields.toArray(res);
2359 if (useCaches) {
2360 publicFields = new SoftReference<>(res);
2361 }
2362 return res;
2363 }
2364
2365 private static void addAll(Collection<Field> c, Field[] o) {
2366 for (int i = 0; i < o.length; i++) {
2367 c.add(o[i]);
2368 }
2369 }
2370
2371
2372 //
2373 //
2374 // java.lang.reflect.Constructor handling
2375 //
2376 //
2377
2378 // Returns an array of "root" constructors. These Constructor
2379 // objects must NOT be propagated to the outside world, but must
2380 // instead be copied via ReflectionFactory.copyConstructor.
2381 private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
2382 checkInitted();
2383 Constructor<T>[] res = null;
2384 if (useCaches) {
2385 clearCachesOnClassRedefinition();
2386 if (publicOnly) {
2387 if (publicConstructors != null) {
2388 res = publicConstructors.get();
2389 }
2390 } else {
2391 if (declaredConstructors != null) {
2392 res = declaredConstructors.get();
2393 }
2394 }
2395 if (res != null) return res;
2396 }
2397 // No cached value available; request value from VM
2398 if (isInterface()) {
2399 @SuppressWarnings("unchecked")
2400 Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
2401 res = temporaryRes;
2402 } else {
2403 res = getDeclaredConstructors0(publicOnly);
2404 }
2405 if (useCaches) {
2406 if (publicOnly) {
2407 publicConstructors = new SoftReference<>(res);
2408 } else {
2409 declaredConstructors = new SoftReference<>(res);
2410 }
2411 }
2412 return res;
2413 }
2414
2415 //
2416 //
2417 // java.lang.reflect.Method handling
2418 //
2419 //
2420
2421 // Returns an array of "root" methods. These Method objects must NOT
2422 // be propagated to the outside world, but must instead be copied
2423 // via ReflectionFactory.copyMethod.
2424 private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2425 checkInitted();
2426 Method[] res = null;
2427 if (useCaches) {
2428 clearCachesOnClassRedefinition();
2429 if (publicOnly) {
2430 if (declaredPublicMethods != null) {
2431 res = declaredPublicMethods.get();
2432 }
2433 } else {
2434 if (declaredMethods != null) {
2435 res = declaredMethods.get();
2436 }
2437 }
2438 if (res != null) return res;
2439 }
2440 // No cached value available; request value from VM
2441 res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2442 if (useCaches) {
2443 if (publicOnly) {
2444 declaredPublicMethods = new SoftReference<>(res);
2445 } else {
2446 declaredMethods = new SoftReference<>(res);
2447 }
2448 }
2449 return res;
2450 }
2451
2452 static class MethodArray {
2453 private Method[] methods;
2454 private int length;
2455
2456 MethodArray() {
2457 methods = new Method[20];
2458 length = 0;
2459 }
2460
2461 void add(Method m) {
2462 if (length == methods.length) {
2463 methods = Arrays.copyOf(methods, 2 * methods.length);
2464 }
2465 methods[length++] = m;
2466 }
2529 newPos++;
2530 }
2531 }
2532 if (newPos != methods.length) {
2533 methods = Arrays.copyOf(methods, newPos);
2534 }
2535 }
2536
2537 Method[] getArray() {
2538 return methods;
2539 }
2540 }
2541
2542
2543 // Returns an array of "root" methods. These Method objects must NOT
2544 // be propagated to the outside world, but must instead be copied
2545 // via ReflectionFactory.copyMethod.
2546 private Method[] privateGetPublicMethods() {
2547 checkInitted();
2548 Method[] res = null;
2549 if (useCaches) {
2550 clearCachesOnClassRedefinition();
2551 if (publicMethods != null) {
2552 res = publicMethods.get();
2553 }
2554 if (res != null) return res;
2555 }
2556
2557 // No cached value available; compute value recursively.
2558 // Start by fetching public declared methods
2559 MethodArray methods = new MethodArray();
2560 {
2561 Method[] tmp = privateGetDeclaredMethods(true);
2562 methods.addAll(tmp);
2563 }
2564 // Now recur over superclass and direct superinterfaces.
2565 // Go over superinterfaces first so we can more easily filter
2566 // out concrete implementations inherited from superclasses at
2567 // the end.
2568 MethodArray inheritedMethods = new MethodArray();
2569 Class<?>[] interfaces = getInterfaces();
2570 for (int i = 0; i < interfaces.length; i++) {
2571 inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
2572 }
2582 if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2583 inheritedMethods.removeByNameAndSignature(m);
2584 }
2585 }
2586 // Insert superclass's inherited methods before
2587 // superinterfaces' to satisfy getMethod's search
2588 // order
2589 supers.addAll(inheritedMethods);
2590 inheritedMethods = supers;
2591 }
2592 }
2593 // Filter out all local methods from inherited ones
2594 for (int i = 0; i < methods.length(); i++) {
2595 Method m = methods.get(i);
2596 inheritedMethods.removeByNameAndSignature(m);
2597 }
2598 methods.addAllIfNotPresent(inheritedMethods);
2599 methods.compactAndTrim();
2600 res = methods.getArray();
2601 if (useCaches) {
2602 publicMethods = new SoftReference<>(res);
2603 }
2604 return res;
2605 }
2606
2607
2608 //
2609 // Helpers for fetchers of one field, method, or constructor
2610 //
2611
2612 private Field searchFields(Field[] fields, String name) {
2613 String internedName = name.intern();
2614 for (int i = 0; i < fields.length; i++) {
2615 if (fields[i].getName() == internedName) {
2616 return getReflectionFactory().copyField(fields[i]);
2617 }
2618 }
2619 return null;
2620 }
2621
2622 private Field getField0(String name) throws NoSuchFieldException {
3101 for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3102 Class<? extends Annotation> annotationClass = e.getKey();
3103 if (AnnotationType.getInstance(annotationClass).isInherited())
3104 annotations.put(annotationClass, e.getValue());
3105 }
3106 annotations.putAll(declaredAnnotations);
3107 }
3108 }
3109
3110 // Annotation types cache their internal (AnnotationType) form
3111
3112 private AnnotationType annotationType;
3113
3114 void setAnnotationType(AnnotationType type) {
3115 annotationType = type;
3116 }
3117
3118 AnnotationType getAnnotationType() {
3119 return annotationType;
3120 }
3121 }
|
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
310 *
311 * </ul>
312 *
313 */
314 public T newInstance()
315 throws InstantiationException, IllegalAccessException
316 {
317 if (System.getSecurityManager() != null) {
318 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
319 }
320 return newInstance0();
321 }
322
323 private T newInstance0()
324 throws InstantiationException, IllegalAccessException
325 {
326 // NOTE: the following code may not be strictly correct under
327 // the current Java memory model.
328
329 // Constructor lookup
330 final ReflectionHelper rh = rh();
331 if (rh.cachedConstructor == null) {
332 if (this == Class.class) {
333 throw new IllegalAccessException(
334 "Can not call newInstance() on the Class for java.lang.Class"
335 );
336 }
337 try {
338 Class<?>[] empty = {};
339 final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
340 // Disable accessibility checks on the constructor
341 // since we have to do the security check here anyway
342 // (the stack depth is wrong for the Constructor's
343 // security check to work)
344 java.security.AccessController.doPrivileged(
345 new java.security.PrivilegedAction<Void>() {
346 public Void run() {
347 c.setAccessible(true);
348 return null;
349 }
350 });
351 rh.cachedConstructor = c;
352 } catch (NoSuchMethodException e) {
353 throw (InstantiationException)
354 new InstantiationException(getName()).initCause(e);
355 }
356 }
357 Constructor<T> tmpConstructor = rh.cachedConstructor;
358 // Security check (same as in java.lang.reflect.Constructor)
359 int modifiers = tmpConstructor.getModifiers();
360 if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
361 Class<?> caller = Reflection.getCallerClass(3);
362 if (rh.newInstanceCallerCache != caller) {
363 Reflection.ensureMemberAccess(caller, this, null, modifiers);
364 rh.newInstanceCallerCache = caller;
365 }
366 }
367 // Run constructor
368 try {
369 return tmpConstructor.newInstance((Object[])null);
370 } catch (InvocationTargetException e) {
371 Unsafe.getUnsafe().throwException(e.getTargetException());
372 // Not reached
373 return null;
374 }
375 }
376
377
378 /**
379 * Determines if the specified {@code Object} is assignment-compatible
380 * with the object represented by this {@code Class}. This method is
381 * the dynamic equivalent of the Java language {@code instanceof}
382 * operator. The method returns {@code true} if the specified
383 * {@code Object} argument is non-null and can be cast to the
384 * reference type represented by this {@code Class} object without
385 * raising a {@code ClassCastException.} It returns {@code false}
386 * otherwise.
387 *
388 * <p> Specifically, if this {@code Class} object represents a
389 * declared class, this method returns {@code true} if the specified
390 * {@code Object} argument is an instance of the represented class (or
391 * of any of its subclasses); it returns {@code false} otherwise. If
392 * this {@code Class} object represents an array class, this method
393 * returns {@code true} if the specified {@code Object} argument
394 * can be converted to an object of the array class by an identity
395 * conversion or by a widening reference conversion; it returns
2192 Class<?> c = this;
2193 while (c.isArray()) {
2194 c = c.getComponentType();
2195 }
2196 String baseName = c.getName();
2197 int index = baseName.lastIndexOf('.');
2198 if (index != -1) {
2199 name = baseName.substring(0, index).replace('.', '/')
2200 +"/"+name;
2201 }
2202 } else {
2203 name = name.substring(1);
2204 }
2205 return name;
2206 }
2207
2208 /**
2209 * Reflection support.
2210 */
2211
2212 // Caches for certain reflective results are stored
2213 // in an auxiliary helper object - so that we only
2214 // need allocate them if used
2215
2216 private static boolean useCaches = true;
2217
2218 // Helper object to hold reflection specific fields
2219 private volatile transient ReflectionHelper<T> rh;
2220
2221 /**
2222 * Return a reference to the ReflectionHelper - creating it if necessary
2223 */
2224 private ReflectionHelper<T> rh() {
2225 if (rh == null) {
2226 synchronized(this) {
2227 if (rh == null)
2228 rh = new ReflectionHelper<>();
2229 }
2230 }
2231 return rh;
2232 }
2233
2234 /**
2235 * Return a reference to the ReflectionHelper if it exists
2236 */
2237 private ReflectionHelper<T> raw_rh() {
2238 return rh;
2239 }
2240
2241
2242 static class ReflectionHelper<T> {
2243
2244 private transient volatile Constructor<T> cachedConstructor;
2245 private transient volatile Class<?> newInstanceCallerCache;
2246
2247 private volatile transient SoftReference<Field[]> declaredFields;
2248 private volatile transient SoftReference<Field[]> publicFields;
2249 private volatile transient SoftReference<Method[]> declaredMethods;
2250 private volatile transient SoftReference<Method[]> publicMethods;
2251 private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
2252 private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
2253 // Intermediate results for getFields and getMethods
2254 private volatile transient SoftReference<Field[]> declaredPublicFields;
2255 private volatile transient SoftReference<Method[]> declaredPublicMethods;
2256
2257 private void clearCachesOnClassRedefinition() {
2258 declaredFields = publicFields = declaredPublicFields = null;
2259 declaredMethods = publicMethods = declaredPublicMethods = null;
2260 declaredConstructors = publicConstructors = null;
2261 }
2262 }
2263
2264 // Incremented by the VM on each call to JVM TI RedefineClasses()
2265 // that redefines this class or a superclass.
2266 private volatile transient int classRedefinedCount = 0;
2267
2268 // Value of classRedefinedCount when we last cleared the cached values
2269 // that are sensitive to class redefinition.
2270 private volatile transient int lastRedefinedCount = 0;
2271
2272 // Clears cached values that might possibly have been obsoleted by
2273 // a class redefinition.
2274 private void clearCachesOnClassRedefinition() {
2275 if (lastRedefinedCount != classRedefinedCount) {
2276 // If there's no ReflectionHelper then there is nothing to clear,
2277 // and we don't want to create the ReflectionHelper unnecessarily
2278 final ReflectionHelper rh = raw_rh();
2279 if (rh != null)
2280 rh.clearCachesOnClassRedefinition();
2281
2282 annotations = declaredAnnotations = null;
2283
2284 // Use of "volatile" (and synchronization by caller in the case
2285 // of annotations) ensures that no thread sees the update to
2286 // lastRedefinedCount before seeing the caches cleared.
2287 // We do not guard against brief windows during which multiple
2288 // threads might redundantly work to fill an empty cache.
2289 lastRedefinedCount = classRedefinedCount;
2290 }
2291 }
2292
2293 // Generic signature handling
2294 private native String getGenericSignature();
2295
2296 // Generic info repository; lazily initialized
2297 private transient ClassRepository genericInfo;
2298
2299 // accessor for factory
2300 private GenericsFactory getFactory() {
2301 // create scope and factory
2313 return genericInfo; //return cached repository
2314 }
2315
2316 // Annotations handling
2317 private native byte[] getRawAnnotations();
2318
2319 native ConstantPool getConstantPool();
2320
2321 //
2322 //
2323 // java.lang.reflect.Field handling
2324 //
2325 //
2326
2327 // Returns an array of "root" fields. These Field objects must NOT
2328 // be propagated to the outside world, but must instead be copied
2329 // via ReflectionFactory.copyField.
2330 private Field[] privateGetDeclaredFields(boolean publicOnly) {
2331 checkInitted();
2332 Field[] res = null;
2333 final ReflectionHelper<T> rh = rh();
2334 if (useCaches) {
2335 clearCachesOnClassRedefinition();
2336 if (publicOnly) {
2337 if (rh.declaredPublicFields != null) {
2338 res = rh.declaredPublicFields.get();
2339 }
2340 } else {
2341 if (rh.declaredFields != null) {
2342 res = rh.declaredFields.get();
2343 }
2344 }
2345 if (res != null) return res;
2346 }
2347 // No cached value available; request value from VM
2348 res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2349 if (useCaches) {
2350 if (publicOnly) {
2351 rh.declaredPublicFields = new SoftReference<>(res);
2352 } else {
2353 rh.declaredFields = new SoftReference<>(res);
2354 }
2355 }
2356 return res;
2357 }
2358
2359 // Returns an array of "root" fields. These Field objects must NOT
2360 // be propagated to the outside world, but must instead be copied
2361 // via ReflectionFactory.copyField.
2362 private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2363 checkInitted();
2364 Field[] res = null;
2365 final ReflectionHelper<T> rh = rh();
2366 if (useCaches) {
2367 clearCachesOnClassRedefinition();
2368 if (rh.publicFields != null) {
2369 res = rh.publicFields.get();
2370 }
2371 if (res != null) return res;
2372 }
2373
2374 // No cached value available; compute value recursively.
2375 // Traverse in correct order for getField().
2376 List<Field> fields = new ArrayList<>();
2377 if (traversedInterfaces == null) {
2378 traversedInterfaces = new HashSet<>();
2379 }
2380
2381 // Local fields
2382 Field[] tmp = privateGetDeclaredFields(true);
2383 addAll(fields, tmp);
2384
2385 // Direct superinterfaces, recursively
2386 for (Class<?> c : getInterfaces()) {
2387 if (!traversedInterfaces.contains(c)) {
2388 traversedInterfaces.add(c);
2389 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2390 }
2391 }
2392
2393 // Direct superclass, recursively
2394 if (!isInterface()) {
2395 Class<?> c = getSuperclass();
2396 if (c != null) {
2397 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2398 }
2399 }
2400
2401 res = new Field[fields.size()];
2402 fields.toArray(res);
2403 if (useCaches) {
2404 rh.publicFields = new SoftReference<>(res);
2405 }
2406 return res;
2407 }
2408
2409 private static void addAll(Collection<Field> c, Field[] o) {
2410 for (int i = 0; i < o.length; i++) {
2411 c.add(o[i]);
2412 }
2413 }
2414
2415
2416 //
2417 //
2418 // java.lang.reflect.Constructor handling
2419 //
2420 //
2421
2422 // Returns an array of "root" constructors. These Constructor
2423 // objects must NOT be propagated to the outside world, but must
2424 // instead be copied via ReflectionFactory.copyConstructor.
2425 private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
2426 checkInitted();
2427 Constructor<T>[] res = null;
2428 final ReflectionHelper<T> rh = rh();
2429 if (useCaches) {
2430 clearCachesOnClassRedefinition();
2431 if (publicOnly) {
2432 if (rh.publicConstructors != null) {
2433 res = rh.publicConstructors.get();
2434 }
2435 } else {
2436 if (rh.declaredConstructors != null) {
2437 res = rh.declaredConstructors.get();
2438 }
2439 }
2440 if (res != null) return res;
2441 }
2442 // No cached value available; request value from VM
2443 if (isInterface()) {
2444 @SuppressWarnings("unchecked")
2445 Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
2446 res = temporaryRes;
2447 } else {
2448 res = getDeclaredConstructors0(publicOnly);
2449 }
2450 if (useCaches) {
2451 if (publicOnly) {
2452 rh.publicConstructors = new SoftReference<>(res);
2453 } else {
2454 rh.declaredConstructors = new SoftReference<>(res);
2455 }
2456 }
2457 return res;
2458 }
2459
2460 //
2461 //
2462 // java.lang.reflect.Method handling
2463 //
2464 //
2465
2466 // Returns an array of "root" methods. These Method objects must NOT
2467 // be propagated to the outside world, but must instead be copied
2468 // via ReflectionFactory.copyMethod.
2469 private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2470 checkInitted();
2471 Method[] res = null;
2472 final ReflectionHelper<T> rh = rh();
2473 if (useCaches) {
2474 clearCachesOnClassRedefinition();
2475 if (publicOnly) {
2476 if (rh.declaredPublicMethods != null) {
2477 res = rh.declaredPublicMethods.get();
2478 }
2479 } else {
2480 if (rh.declaredMethods != null) {
2481 res = rh.declaredMethods.get();
2482 }
2483 }
2484 if (res != null) return res;
2485 }
2486 // No cached value available; request value from VM
2487 res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2488 if (useCaches) {
2489 if (publicOnly) {
2490 rh.declaredPublicMethods = new SoftReference<>(res);
2491 } else {
2492 rh.declaredMethods = new SoftReference<>(res);
2493 }
2494 }
2495 return res;
2496 }
2497
2498 static class MethodArray {
2499 private Method[] methods;
2500 private int length;
2501
2502 MethodArray() {
2503 methods = new Method[20];
2504 length = 0;
2505 }
2506
2507 void add(Method m) {
2508 if (length == methods.length) {
2509 methods = Arrays.copyOf(methods, 2 * methods.length);
2510 }
2511 methods[length++] = m;
2512 }
2575 newPos++;
2576 }
2577 }
2578 if (newPos != methods.length) {
2579 methods = Arrays.copyOf(methods, newPos);
2580 }
2581 }
2582
2583 Method[] getArray() {
2584 return methods;
2585 }
2586 }
2587
2588
2589 // Returns an array of "root" methods. These Method objects must NOT
2590 // be propagated to the outside world, but must instead be copied
2591 // via ReflectionFactory.copyMethod.
2592 private Method[] privateGetPublicMethods() {
2593 checkInitted();
2594 Method[] res = null;
2595 final ReflectionHelper<T> rh = rh();
2596 if (useCaches) {
2597 clearCachesOnClassRedefinition();
2598 if (rh.publicMethods != null) {
2599 res = rh.publicMethods.get();
2600 }
2601 if (res != null) return res;
2602 }
2603
2604 // No cached value available; compute value recursively.
2605 // Start by fetching public declared methods
2606 MethodArray methods = new MethodArray();
2607 {
2608 Method[] tmp = privateGetDeclaredMethods(true);
2609 methods.addAll(tmp);
2610 }
2611 // Now recur over superclass and direct superinterfaces.
2612 // Go over superinterfaces first so we can more easily filter
2613 // out concrete implementations inherited from superclasses at
2614 // the end.
2615 MethodArray inheritedMethods = new MethodArray();
2616 Class<?>[] interfaces = getInterfaces();
2617 for (int i = 0; i < interfaces.length; i++) {
2618 inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
2619 }
2629 if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2630 inheritedMethods.removeByNameAndSignature(m);
2631 }
2632 }
2633 // Insert superclass's inherited methods before
2634 // superinterfaces' to satisfy getMethod's search
2635 // order
2636 supers.addAll(inheritedMethods);
2637 inheritedMethods = supers;
2638 }
2639 }
2640 // Filter out all local methods from inherited ones
2641 for (int i = 0; i < methods.length(); i++) {
2642 Method m = methods.get(i);
2643 inheritedMethods.removeByNameAndSignature(m);
2644 }
2645 methods.addAllIfNotPresent(inheritedMethods);
2646 methods.compactAndTrim();
2647 res = methods.getArray();
2648 if (useCaches) {
2649 rh.publicMethods = new SoftReference<>(res);
2650 }
2651 return res;
2652 }
2653
2654
2655 //
2656 // Helpers for fetchers of one field, method, or constructor
2657 //
2658
2659 private Field searchFields(Field[] fields, String name) {
2660 String internedName = name.intern();
2661 for (int i = 0; i < fields.length; i++) {
2662 if (fields[i].getName() == internedName) {
2663 return getReflectionFactory().copyField(fields[i]);
2664 }
2665 }
2666 return null;
2667 }
2668
2669 private Field getField0(String name) throws NoSuchFieldException {
3148 for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3149 Class<? extends Annotation> annotationClass = e.getKey();
3150 if (AnnotationType.getInstance(annotationClass).isInherited())
3151 annotations.put(annotationClass, e.getValue());
3152 }
3153 annotations.putAll(declaredAnnotations);
3154 }
3155 }
3156
3157 // Annotation types cache their internal (AnnotationType) form
3158
3159 private AnnotationType annotationType;
3160
3161 void setAnnotationType(AnnotationType type) {
3162 annotationType = type;
3163 }
3164
3165 AnnotationType getAnnotationType() {
3166 return annotationType;
3167 }
3168
3169 }
|