Print this page


Split Close
Expand all
Collapse all
          --- old/src/share/classes/java/lang/Class.java
          +++ new/src/share/classes/java/lang/Class.java
   1    1  /*
   2      - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
        2 + * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
   3    3   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4    4   *
   5    5   * This code is free software; you can redistribute it and/or modify it
   6    6   * under the terms of the GNU General Public License version 2 only, as
   7    7   * published by the Free Software Foundation.  Oracle designates this
   8    8   * particular file as subject to the "Classpath" exception as provided
   9    9   * by Oracle in the LICENSE file that accompanied this code.
  10   10   *
  11   11   * This code is distributed in the hope that it will be useful, but WITHOUT
  12   12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
↓ open down ↓ 88 lines elided ↑ open up ↑
 101  101   * @param <T> the type of the class modeled by this {@code Class}
 102  102   * object.  For example, the type of {@code String.class} is {@code
 103  103   * Class<String>}.  Use {@code Class<?>} if the class being modeled is
 104  104   * unknown.
 105  105   *
 106  106   * @author  unascribed
 107  107   * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
 108  108   * @since   JDK1.0
 109  109   */
 110  110  public final
 111      -    class Class<T> implements java.io.Serializable,
 112      -                              java.lang.reflect.GenericDeclaration,
 113      -                              java.lang.reflect.Type,
 114      -                              java.lang.reflect.AnnotatedElement {
      111 +     class Class<T> implements java.io.Serializable,
      112 +                               java.lang.reflect.GenericDeclaration,
      113 +                               java.lang.reflect.Type,
      114 +                               java.lang.reflect.AnnotatedElement {
 115  115      private static final int ANNOTATION= 0x00002000;
 116  116      private static final int ENUM      = 0x00004000;
 117  117      private static final int SYNTHETIC = 0x00001000;
 118      -
      118 +    
 119  119      private static native void registerNatives();
 120  120      static {
 121  121          registerNatives();
 122  122      }
 123  123  
 124  124      /*
 125  125       * Constructor. Only the Java Virtual Machine creates Class
 126  126       * objects.
 127  127       */
 128  128      private Class() {}
↓ open down ↓ 191 lines elided ↑ open up ↑
 320  320          return newInstance0();
 321  321      }
 322  322  
 323  323      private T newInstance0()
 324  324          throws InstantiationException, IllegalAccessException
 325  325      {
 326  326          // NOTE: the following code may not be strictly correct under
 327  327          // the current Java memory model.
 328  328  
 329  329          // Constructor lookup
 330      -        if (cachedConstructor == null) {
      330 +        final ReflectionHelper rh = rh();
      331 +        if (rh.cachedConstructor == null) {
 331  332              if (this == Class.class) {
 332  333                  throw new IllegalAccessException(
 333  334                      "Can not call newInstance() on the Class for java.lang.Class"
 334  335                  );
 335  336              }
 336  337              try {
 337  338                  Class<?>[] empty = {};
 338  339                  final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
 339  340                  // Disable accessibility checks on the constructor
 340  341                  // since we have to do the security check here anyway
 341  342                  // (the stack depth is wrong for the Constructor's
 342  343                  // security check to work)
 343  344                  java.security.AccessController.doPrivileged(
 344  345                      new java.security.PrivilegedAction<Void>() {
 345  346                          public Void run() {
 346  347                                  c.setAccessible(true);
 347  348                                  return null;
 348  349                              }
 349  350                          });
 350      -                cachedConstructor = c;
      351 +                rh.cachedConstructor = c;
 351  352              } catch (NoSuchMethodException e) {
 352  353                  throw (InstantiationException)
 353  354                      new InstantiationException(getName()).initCause(e);
 354  355              }
 355  356          }
 356      -        Constructor<T> tmpConstructor = cachedConstructor;
      357 +        Constructor<T> tmpConstructor = rh.cachedConstructor;
 357  358          // Security check (same as in java.lang.reflect.Constructor)
 358  359          int modifiers = tmpConstructor.getModifiers();
 359  360          if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
 360  361              Class<?> caller = Reflection.getCallerClass(3);
 361      -            if (newInstanceCallerCache != caller) {
      362 +            if (rh.newInstanceCallerCache != caller) {
 362  363                  Reflection.ensureMemberAccess(caller, this, null, modifiers);
 363      -                newInstanceCallerCache = caller;
      364 +                rh.newInstanceCallerCache = caller;
 364  365              }
 365  366          }
 366  367          // Run constructor
 367  368          try {
 368  369              return tmpConstructor.newInstance((Object[])null);
 369  370          } catch (InvocationTargetException e) {
 370  371              Unsafe.getUnsafe().throwException(e.getTargetException());
 371  372              // Not reached
 372  373              return null;
 373  374          }
 374  375      }
 375      -    private volatile transient Constructor<T> cachedConstructor;
 376      -    private volatile transient Class<?>       newInstanceCallerCache;
 377  376  
 378  377  
 379  378      /**
 380  379       * Determines if the specified {@code Object} is assignment-compatible
 381  380       * with the object represented by this {@code Class}.  This method is
 382  381       * the dynamic equivalent of the Java language {@code instanceof}
 383  382       * operator. The method returns {@code true} if the specified
 384  383       * {@code Object} argument is non-null and can be cast to the
 385  384       * reference type represented by this {@code Class} object without
 386  385       * raising a {@code ClassCastException.} It returns {@code false}
↓ open down ↓ 1816 lines elided ↑ open up ↑
2203 2202          } else {
2204 2203              name = name.substring(1);
2205 2204          }
2206 2205          return name;
2207 2206      }
2208 2207  
2209 2208      /**
2210 2209       * Reflection support.
2211 2210       */
2212 2211  
2213      -    // Caches for certain reflective results
     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 +
2214 2216      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 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 +
2225 2264      // Incremented by the VM on each call to JVM TI RedefineClasses()
2226 2265      // that redefines this class or a superclass.
2227 2266      private volatile transient int classRedefinedCount = 0;
2228 2267  
2229 2268      // Value of classRedefinedCount when we last cleared the cached values
2230 2269      // that are sensitive to class redefinition.
2231 2270      private volatile transient int lastRedefinedCount = 0;
2232 2271  
2233 2272      // Clears cached values that might possibly have been obsoleted by
2234 2273      // a class redefinition.
2235 2274      private void clearCachesOnClassRedefinition() {
2236 2275          if (lastRedefinedCount != classRedefinedCount) {
2237      -            declaredFields = publicFields = declaredPublicFields = null;
2238      -            declaredMethods = publicMethods = declaredPublicMethods = null;
2239      -            declaredConstructors = publicConstructors = null;
     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 +
2240 2282              annotations = declaredAnnotations = null;
2241 2283  
2242 2284              // Use of "volatile" (and synchronization by caller in the case
2243 2285              // of annotations) ensures that no thread sees the update to
2244 2286              // lastRedefinedCount before seeing the caches cleared.
2245 2287              // We do not guard against brief windows during which multiple
2246 2288              // threads might redundantly work to fill an empty cache.
2247 2289              lastRedefinedCount = classRedefinedCount;
2248 2290          }
2249 2291      }
↓ open down ↓ 31 lines elided ↑ open up ↑
2281 2323      // java.lang.reflect.Field handling
2282 2324      //
2283 2325      //
2284 2326  
2285 2327      // Returns an array of "root" fields. These Field objects must NOT
2286 2328      // be propagated to the outside world, but must instead be copied
2287 2329      // via ReflectionFactory.copyField.
2288 2330      private Field[] privateGetDeclaredFields(boolean publicOnly) {
2289 2331          checkInitted();
2290 2332          Field[] res = null;
     2333 +        final ReflectionHelper<T> rh = rh();
2291 2334          if (useCaches) {
2292 2335              clearCachesOnClassRedefinition();
2293 2336              if (publicOnly) {
2294      -                if (declaredPublicFields != null) {
2295      -                    res = declaredPublicFields.get();
     2337 +                if (rh.declaredPublicFields != null) {
     2338 +                    res = rh.declaredPublicFields.get();
2296 2339                  }
2297 2340              } else {
2298      -                if (declaredFields != null) {
2299      -                    res = declaredFields.get();
     2341 +                if (rh.declaredFields != null) {
     2342 +                    res = rh.declaredFields.get();
2300 2343                  }
2301 2344              }
2302 2345              if (res != null) return res;
2303 2346          }
2304 2347          // No cached value available; request value from VM
2305 2348          res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2306 2349          if (useCaches) {
2307 2350              if (publicOnly) {
2308      -                declaredPublicFields = new SoftReference<>(res);
     2351 +                rh.declaredPublicFields = new SoftReference<>(res);
2309 2352              } else {
2310      -                declaredFields = new SoftReference<>(res);
     2353 +                rh.declaredFields = new SoftReference<>(res);
2311 2354              }
2312 2355          }
2313 2356          return res;
2314 2357      }
2315 2358  
2316 2359      // Returns an array of "root" fields. These Field objects must NOT
2317 2360      // be propagated to the outside world, but must instead be copied
2318 2361      // via ReflectionFactory.copyField.
2319 2362      private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2320 2363          checkInitted();
2321 2364          Field[] res = null;
     2365 +        final ReflectionHelper<T> rh = rh();
2322 2366          if (useCaches) {
2323 2367              clearCachesOnClassRedefinition();
2324      -            if (publicFields != null) {
2325      -                res = publicFields.get();
     2368 +            if (rh.publicFields != null) {
     2369 +                res = rh.publicFields.get();
2326 2370              }
2327 2371              if (res != null) return res;
2328 2372          }
2329 2373  
2330 2374          // No cached value available; compute value recursively.
2331 2375          // Traverse in correct order for getField().
2332 2376          List<Field> fields = new ArrayList<>();
2333 2377          if (traversedInterfaces == null) {
2334 2378              traversedInterfaces = new HashSet<>();
2335 2379          }
↓ open down ↓ 14 lines elided ↑ open up ↑
2350 2394          if (!isInterface()) {
2351 2395              Class<?> c = getSuperclass();
2352 2396              if (c != null) {
2353 2397                  addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2354 2398              }
2355 2399          }
2356 2400  
2357 2401          res = new Field[fields.size()];
2358 2402          fields.toArray(res);
2359 2403          if (useCaches) {
2360      -            publicFields = new SoftReference<>(res);
     2404 +            rh.publicFields = new SoftReference<>(res);
2361 2405          }
2362 2406          return res;
2363 2407      }
2364 2408  
2365 2409      private static void addAll(Collection<Field> c, Field[] o) {
2366 2410          for (int i = 0; i < o.length; i++) {
2367 2411              c.add(o[i]);
2368 2412          }
2369 2413      }
2370 2414  
↓ open down ↓ 3 lines elided ↑ open up ↑
2374 2418      // java.lang.reflect.Constructor handling
2375 2419      //
2376 2420      //
2377 2421  
2378 2422      // Returns an array of "root" constructors. These Constructor
2379 2423      // objects must NOT be propagated to the outside world, but must
2380 2424      // instead be copied via ReflectionFactory.copyConstructor.
2381 2425      private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
2382 2426          checkInitted();
2383 2427          Constructor<T>[] res = null;
     2428 +        final ReflectionHelper<T> rh = rh();
2384 2429          if (useCaches) {
2385 2430              clearCachesOnClassRedefinition();
2386 2431              if (publicOnly) {
2387      -                if (publicConstructors != null) {
2388      -                    res = publicConstructors.get();
     2432 +                if (rh.publicConstructors != null) {
     2433 +                    res = rh.publicConstructors.get();
2389 2434                  }
2390 2435              } else {
2391      -                if (declaredConstructors != null) {
2392      -                    res = declaredConstructors.get();
     2436 +                if (rh.declaredConstructors != null) {
     2437 +                    res = rh.declaredConstructors.get();
2393 2438                  }
2394 2439              }
2395 2440              if (res != null) return res;
2396 2441          }
2397 2442          // No cached value available; request value from VM
2398 2443          if (isInterface()) {
2399 2444              @SuppressWarnings("unchecked")
2400 2445              Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
2401 2446              res = temporaryRes;
2402 2447          } else {
2403 2448              res = getDeclaredConstructors0(publicOnly);
2404 2449          }
2405 2450          if (useCaches) {
2406 2451              if (publicOnly) {
2407      -                publicConstructors = new SoftReference<>(res);
     2452 +                rh.publicConstructors = new SoftReference<>(res);
2408 2453              } else {
2409      -                declaredConstructors = new SoftReference<>(res);
     2454 +                rh.declaredConstructors = new SoftReference<>(res);
2410 2455              }
2411 2456          }
2412 2457          return res;
2413 2458      }
2414 2459  
2415 2460      //
2416 2461      //
2417 2462      // java.lang.reflect.Method handling
2418 2463      //
2419 2464      //
2420 2465  
2421 2466      // Returns an array of "root" methods. These Method objects must NOT
2422 2467      // be propagated to the outside world, but must instead be copied
2423 2468      // via ReflectionFactory.copyMethod.
2424 2469      private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2425 2470          checkInitted();
2426 2471          Method[] res = null;
     2472 +        final ReflectionHelper<T> rh = rh();
2427 2473          if (useCaches) {
2428 2474              clearCachesOnClassRedefinition();
2429 2475              if (publicOnly) {
2430      -                if (declaredPublicMethods != null) {
2431      -                    res = declaredPublicMethods.get();
     2476 +                if (rh.declaredPublicMethods != null) {
     2477 +                    res = rh.declaredPublicMethods.get();
2432 2478                  }
2433 2479              } else {
2434      -                if (declaredMethods != null) {
2435      -                    res = declaredMethods.get();
     2480 +                if (rh.declaredMethods != null) {
     2481 +                    res = rh.declaredMethods.get();
2436 2482                  }
2437 2483              }
2438 2484              if (res != null) return res;
2439 2485          }
2440 2486          // No cached value available; request value from VM
2441 2487          res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2442 2488          if (useCaches) {
2443 2489              if (publicOnly) {
2444      -                declaredPublicMethods = new SoftReference<>(res);
     2490 +                rh.declaredPublicMethods = new SoftReference<>(res);
2445 2491              } else {
2446      -                declaredMethods = new SoftReference<>(res);
     2492 +                rh.declaredMethods = new SoftReference<>(res);
2447 2493              }
2448 2494          }
2449 2495          return res;
2450 2496      }
2451 2497  
2452 2498      static class MethodArray {
2453 2499          private Method[] methods;
2454 2500          private int length;
2455 2501  
2456 2502          MethodArray() {
↓ open down ↓ 82 lines elided ↑ open up ↑
2539 2585          }
2540 2586      }
2541 2587  
2542 2588  
2543 2589      // Returns an array of "root" methods. These Method objects must NOT
2544 2590      // be propagated to the outside world, but must instead be copied
2545 2591      // via ReflectionFactory.copyMethod.
2546 2592      private Method[] privateGetPublicMethods() {
2547 2593          checkInitted();
2548 2594          Method[] res = null;
     2595 +        final ReflectionHelper<T> rh = rh();
2549 2596          if (useCaches) {
2550 2597              clearCachesOnClassRedefinition();
2551      -            if (publicMethods != null) {
2552      -                res = publicMethods.get();
     2598 +            if (rh.publicMethods != null) {
     2599 +                res = rh.publicMethods.get();
2553 2600              }
2554 2601              if (res != null) return res;
2555 2602          }
2556 2603  
2557 2604          // No cached value available; compute value recursively.
2558 2605          // Start by fetching public declared methods
2559 2606          MethodArray methods = new MethodArray();
2560 2607          {
2561 2608                  Method[] tmp = privateGetDeclaredMethods(true);
2562 2609              methods.addAll(tmp);
↓ open down ↓ 29 lines elided ↑ open up ↑
2592 2639          }
2593 2640          // Filter out all local methods from inherited ones
2594 2641          for (int i = 0; i < methods.length(); i++) {
2595 2642              Method m = methods.get(i);
2596 2643              inheritedMethods.removeByNameAndSignature(m);
2597 2644          }
2598 2645          methods.addAllIfNotPresent(inheritedMethods);
2599 2646          methods.compactAndTrim();
2600 2647          res = methods.getArray();
2601 2648          if (useCaches) {
2602      -            publicMethods = new SoftReference<>(res);
     2649 +            rh.publicMethods = new SoftReference<>(res);
2603 2650          }
2604 2651          return res;
2605 2652      }
2606 2653  
2607 2654  
2608 2655      //
2609 2656      // Helpers for fetchers of one field, method, or constructor
2610 2657      //
2611 2658  
2612 2659      private Field searchFields(Field[] fields, String name) {
↓ open down ↓ 498 lines elided ↑ open up ↑
3111 3158  
3112 3159      private AnnotationType annotationType;
3113 3160  
3114 3161      void setAnnotationType(AnnotationType type) {
3115 3162          annotationType = type;
3116 3163      }
3117 3164  
3118 3165      AnnotationType getAnnotationType() {
3119 3166          return annotationType;
3120 3167      }
     3168 +
3121 3169  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX