< prev index next >

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

Print this page

 454      * @throws    ClassNotFoundException if the class cannot be located
 455      *
 456      * @jls 12.2 Loading of Classes and Interfaces
 457      * @jls 12.3 Linking of Classes and Interfaces
 458      * @jls 12.4 Initialization of Classes and Interfaces
 459      */
 460     @CallerSensitive
 461     public static Class<?> forName(String className)
 462                 throws ClassNotFoundException {
 463         Class<?> caller = Reflection.getCallerClass();
 464         return forName(className, caller);
 465     }
 466 
 467     // Caller-sensitive adapter method for reflective invocation
 468     @CallerSensitiveAdapter
 469     private static Class<?> forName(String className, Class<?> caller)
 470             throws ClassNotFoundException {
 471         validateClassNameLength(className);
 472         ClassLoader loader = (caller == null) ? ClassLoader.getSystemClassLoader()
 473                                               : ClassLoader.getClassLoader(caller);













 474         return forName0(className, true, loader, caller);
 475     }
 476 
 477     /**
 478      * Returns the {@code Class} object associated with the class or
 479      * interface with the given string name, using the given class loader.
 480      * Given the {@linkplain ClassLoader##binary-name binary name} for a class or interface,
 481      * this method attempts to locate and load the class or interface. The specified
 482      * class loader is used to load the class or interface.  If the parameter
 483      * {@code loader} is {@code null}, the class is loaded through the bootstrap
 484      * class loader.  The class is initialized only if the
 485      * {@code initialize} parameter is {@code true} and if it has
 486      * not been initialized earlier.
 487      *
 488      * <p> This method cannot be used to obtain any of the {@code Class} objects
 489      * representing primitive types or void, hidden classes or interfaces,
 490      * or array classes whose element type is a hidden class or interface.
 491      * If {@code name} denotes a primitive type or void, for example {@code I},
 492      * an attempt will be made to locate a user-defined class in the unnamed package
 493      * whose name is {@code I} instead.

 535      *
 536      * @throws    LinkageError if the linkage fails
 537      * @throws    ExceptionInInitializerError if the initialization provoked
 538      *            by this method fails
 539      * @throws    ClassNotFoundException if the class cannot be located by
 540      *            the specified class loader
 541      *
 542      * @see       java.lang.Class#forName(String)
 543      * @see       java.lang.ClassLoader
 544      *
 545      * @jls 12.2 Loading of Classes and Interfaces
 546      * @jls 12.3 Linking of Classes and Interfaces
 547      * @jls 12.4 Initialization of Classes and Interfaces
 548      * @jls 13.1 The Form of a Binary
 549      * @since     1.2
 550      */
 551     public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
 552         throws ClassNotFoundException
 553     {
 554         validateClassNameLength(name);
















 555         return forName0(name, initialize, loader, null);
 556     }
 557 
 558     /** Called after security check for system loader access checks have been made. */
 559     private static native Class<?> forName0(String name, boolean initialize,
 560                                             ClassLoader loader,
 561                                             Class<?> caller)
 562         throws ClassNotFoundException;
 563 
 564 
 565     /**
 566      * Returns the {@code Class} with the given {@linkplain ClassLoader##binary-name
 567      * binary name} in the given module.
 568      *
 569      * <p> This method attempts to locate and load the class or interface.
 570      * It does not link the class, and does not run the class initializer.
 571      * If the class is not found, this method returns {@code null}. </p>
 572      *
 573      * <p> If the class loader of the given module defines other modules and
 574      * the given name is a class defined in a different module, this method

2767     }
2768 
2769     /**
2770      * Atomic operations support.
2771      */
2772     private static class Atomic {
2773         // initialize Unsafe machinery here, since we need to call Class.class instance method
2774         // and have to avoid calling it in the static initializer of the Class class...
2775         private static final Unsafe unsafe = Unsafe.getUnsafe();
2776         // offset of Class.reflectionData instance field
2777         private static final long reflectionDataOffset
2778                 = unsafe.objectFieldOffset(Class.class, "reflectionData");
2779         // offset of Class.annotationType instance field
2780         private static final long annotationTypeOffset
2781                 = unsafe.objectFieldOffset(Class.class, "annotationType");
2782         // offset of Class.annotationData instance field
2783         private static final long annotationDataOffset
2784                 = unsafe.objectFieldOffset(Class.class, "annotationData");
2785 
2786         static <T> boolean casReflectionData(Class<?> clazz,
2787                                              SoftReference<ReflectionData<T>> oldData,
2788                                              SoftReference<ReflectionData<T>> newData) {
2789             return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
2790         }
2791 
2792         static boolean casAnnotationType(Class<?> clazz,
2793                                          AnnotationType oldType,
2794                                          AnnotationType newType) {
2795             return unsafe.compareAndSetReference(clazz, annotationTypeOffset, oldType, newType);
2796         }
2797 
2798         static boolean casAnnotationData(Class<?> clazz,
2799                                          AnnotationData oldData,
2800                                          AnnotationData newData) {
2801             return unsafe.compareAndSetReference(clazz, annotationDataOffset, oldData, newData);
2802         }
2803     }
2804 
2805     /**
2806      * Reflection support.
2807      */
2808 

2816         volatile Constructor<T>[] declaredConstructors;
2817         volatile Constructor<T>[] publicConstructors;
2818         // Intermediate results for getFields and getMethods
2819         volatile Field[] declaredPublicFields;
2820         volatile Method[] declaredPublicMethods;
2821         volatile Class<?>[] interfaces;
2822 
2823         // Cached names
2824         String simpleName;
2825         String canonicalName;
2826         static final String NULL_SENTINEL = new String();
2827 
2828         // Value of classRedefinedCount when we created this ReflectionData instance
2829         final int redefinedCount;
2830 
2831         ReflectionData(int redefinedCount) {
2832             this.redefinedCount = redefinedCount;
2833         }
2834     }
2835 
2836     private transient volatile SoftReference<ReflectionData<T>> reflectionData;
2837 
2838     // Incremented by the VM on each call to JVM TI RedefineClasses()
2839     // that redefines this class or a superclass.
2840     private transient volatile int classRedefinedCount;
2841 
2842     // Lazily create and cache ReflectionData
2843     private ReflectionData<T> reflectionData() {
2844         SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2845         int classRedefinedCount = this.classRedefinedCount;
2846         ReflectionData<T> rd;
2847         if (reflectionData != null &&
2848             (rd = reflectionData.get()) != null &&
2849             rd.redefinedCount == classRedefinedCount) {
2850             return rd;
2851         }
2852         // else no SoftReference or cleared SoftReference or stale ReflectionData
2853         // -> create and replace new instance
2854         return newReflectionData(reflectionData, classRedefinedCount);
2855     }
2856 
2857     private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
2858                                                 int classRedefinedCount) {
2859         while (true) {
2860             ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2861             // try to CAS it...
2862             if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
2863                 return rd;
2864             }
2865             // else retry
2866             oldReflectionData = this.reflectionData;
2867             classRedefinedCount = this.classRedefinedCount;
2868             if (oldReflectionData != null &&
2869                 (rd = oldReflectionData.get()) != null &&
2870                 rd.redefinedCount == classRedefinedCount) {
2871                 return rd;
2872             }
2873         }
2874     }
2875 
2876     // Generic signature handling
2877     private native String getGenericSignature0();
2878 
2879     // Generic info repository; lazily initialized
2880     private transient volatile ClassRepository genericInfo;
2881 
2882     // accessor for factory
2883     private GenericsFactory getFactory() {
2884         // create scope and factory
2885         return CoreReflectionFactory.make(this, ClassScope.make(this));
2886     }
2887 
2888     // accessor for generic info repository;
2889     // generic info is lazily initialized
2890     private ClassRepository getGenericInfo() {

4147       * the original setting of ACC_SUPER.
4148       *
4149       * If this {@code Class} object represents a primitive type or
4150       * void, the flags are {@code PUBLIC}, {@code ABSTRACT}, and
4151       * {@code FINAL}.
4152       * If this {@code Class} object represents an array type, return 0.
4153       */
4154      int getClassFileAccessFlags() {
4155          return classFileAccessFlags;
4156      }
4157 
4158     // Validates the length of the class name and throws an exception if it exceeds the maximum allowed length.
4159     private static void validateClassNameLength(String name) throws ClassNotFoundException {
4160         if (!ModifiedUtf.isValidLengthInConstantPool(name)) {
4161             throw new ClassNotFoundException(
4162                     "Class name length exceeds limit of "
4163                     + ModifiedUtf.CONSTANT_POOL_UTF8_MAX_BYTES
4164                     + ": " + name.substring(0,256) + "...");
4165         }
4166     }

















































4167 }

 454      * @throws    ClassNotFoundException if the class cannot be located
 455      *
 456      * @jls 12.2 Loading of Classes and Interfaces
 457      * @jls 12.3 Linking of Classes and Interfaces
 458      * @jls 12.4 Initialization of Classes and Interfaces
 459      */
 460     @CallerSensitive
 461     public static Class<?> forName(String className)
 462                 throws ClassNotFoundException {
 463         Class<?> caller = Reflection.getCallerClass();
 464         return forName(className, caller);
 465     }
 466 
 467     // Caller-sensitive adapter method for reflective invocation
 468     @CallerSensitiveAdapter
 469     private static Class<?> forName(String className, Class<?> caller)
 470             throws ClassNotFoundException {
 471         validateClassNameLength(className);
 472         ClassLoader loader = (caller == null) ? ClassLoader.getSystemClassLoader()
 473                                               : ClassLoader.getClassLoader(caller);
 474         if (loader instanceof BuiltinClassLoader bcl) {
 475             if (bcl.usePositiveCache) {
 476                 Class<?> result = bcl.checkPositiveLookupCache(className);
 477                 if (result != null) {
 478                     // forName(String, Class) API will always initialize the class
 479                     Unsafe.getUnsafe().ensureClassInitialized(result);
 480                     return result;
 481                 }
 482             }
 483             if (bcl.useNegativeCache && bcl.checkNegativeLookupCache(className)) {
 484                 throw new ClassNotFoundException(className);
 485             }
 486         }
 487         return forName0(className, true, loader, caller);
 488     }
 489 
 490     /**
 491      * Returns the {@code Class} object associated with the class or
 492      * interface with the given string name, using the given class loader.
 493      * Given the {@linkplain ClassLoader##binary-name binary name} for a class or interface,
 494      * this method attempts to locate and load the class or interface. The specified
 495      * class loader is used to load the class or interface.  If the parameter
 496      * {@code loader} is {@code null}, the class is loaded through the bootstrap
 497      * class loader.  The class is initialized only if the
 498      * {@code initialize} parameter is {@code true} and if it has
 499      * not been initialized earlier.
 500      *
 501      * <p> This method cannot be used to obtain any of the {@code Class} objects
 502      * representing primitive types or void, hidden classes or interfaces,
 503      * or array classes whose element type is a hidden class or interface.
 504      * If {@code name} denotes a primitive type or void, for example {@code I},
 505      * an attempt will be made to locate a user-defined class in the unnamed package
 506      * whose name is {@code I} instead.

 548      *
 549      * @throws    LinkageError if the linkage fails
 550      * @throws    ExceptionInInitializerError if the initialization provoked
 551      *            by this method fails
 552      * @throws    ClassNotFoundException if the class cannot be located by
 553      *            the specified class loader
 554      *
 555      * @see       java.lang.Class#forName(String)
 556      * @see       java.lang.ClassLoader
 557      *
 558      * @jls 12.2 Loading of Classes and Interfaces
 559      * @jls 12.3 Linking of Classes and Interfaces
 560      * @jls 12.4 Initialization of Classes and Interfaces
 561      * @jls 13.1 The Form of a Binary
 562      * @since     1.2
 563      */
 564     public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
 565         throws ClassNotFoundException
 566     {
 567         validateClassNameLength(name);
 568 
 569         if (loader instanceof BuiltinClassLoader bcl) {
 570             if (bcl.usePositiveCache) {
 571                 Class<?> result = bcl.checkPositiveLookupCache(name);
 572                 if (result != null) {
 573                     if (initialize) {
 574                         Unsafe.getUnsafe().ensureClassInitialized(result);
 575                     }
 576                     return result;
 577                 }
 578             }
 579            if (bcl.useNegativeCache && bcl.checkNegativeLookupCache(name)) {
 580                 throw new ClassNotFoundException(name);
 581             }
 582         }
 583 
 584         return forName0(name, initialize, loader, null);
 585     }
 586 
 587     /** Called after security check for system loader access checks have been made. */
 588     private static native Class<?> forName0(String name, boolean initialize,
 589                                             ClassLoader loader,
 590                                             Class<?> caller)
 591         throws ClassNotFoundException;
 592 
 593 
 594     /**
 595      * Returns the {@code Class} with the given {@linkplain ClassLoader##binary-name
 596      * binary name} in the given module.
 597      *
 598      * <p> This method attempts to locate and load the class or interface.
 599      * It does not link the class, and does not run the class initializer.
 600      * If the class is not found, this method returns {@code null}. </p>
 601      *
 602      * <p> If the class loader of the given module defines other modules and
 603      * the given name is a class defined in a different module, this method

2796     }
2797 
2798     /**
2799      * Atomic operations support.
2800      */
2801     private static class Atomic {
2802         // initialize Unsafe machinery here, since we need to call Class.class instance method
2803         // and have to avoid calling it in the static initializer of the Class class...
2804         private static final Unsafe unsafe = Unsafe.getUnsafe();
2805         // offset of Class.reflectionData instance field
2806         private static final long reflectionDataOffset
2807                 = unsafe.objectFieldOffset(Class.class, "reflectionData");
2808         // offset of Class.annotationType instance field
2809         private static final long annotationTypeOffset
2810                 = unsafe.objectFieldOffset(Class.class, "annotationType");
2811         // offset of Class.annotationData instance field
2812         private static final long annotationDataOffset
2813                 = unsafe.objectFieldOffset(Class.class, "annotationData");
2814 
2815         static <T> boolean casReflectionData(Class<?> clazz,
2816                                              ReflectionData<T> oldData,
2817                                              ReflectionData<T> newData) {
2818             return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
2819         }
2820 
2821         static boolean casAnnotationType(Class<?> clazz,
2822                                          AnnotationType oldType,
2823                                          AnnotationType newType) {
2824             return unsafe.compareAndSetReference(clazz, annotationTypeOffset, oldType, newType);
2825         }
2826 
2827         static boolean casAnnotationData(Class<?> clazz,
2828                                          AnnotationData oldData,
2829                                          AnnotationData newData) {
2830             return unsafe.compareAndSetReference(clazz, annotationDataOffset, oldData, newData);
2831         }
2832     }
2833 
2834     /**
2835      * Reflection support.
2836      */
2837 

2845         volatile Constructor<T>[] declaredConstructors;
2846         volatile Constructor<T>[] publicConstructors;
2847         // Intermediate results for getFields and getMethods
2848         volatile Field[] declaredPublicFields;
2849         volatile Method[] declaredPublicMethods;
2850         volatile Class<?>[] interfaces;
2851 
2852         // Cached names
2853         String simpleName;
2854         String canonicalName;
2855         static final String NULL_SENTINEL = new String();
2856 
2857         // Value of classRedefinedCount when we created this ReflectionData instance
2858         final int redefinedCount;
2859 
2860         ReflectionData(int redefinedCount) {
2861             this.redefinedCount = redefinedCount;
2862         }
2863     }
2864 
2865     private transient volatile ReflectionData<T> reflectionData;
2866 
2867     // Incremented by the VM on each call to JVM TI RedefineClasses()
2868     // that redefines this class or a superclass.
2869     private transient volatile int classRedefinedCount;
2870 
2871     // Lazily create and cache ReflectionData
2872     private ReflectionData<T> reflectionData() {
2873         ReflectionData<T> reflectionData = this.reflectionData;
2874         int classRedefinedCount = this.classRedefinedCount;

2875         if (reflectionData != null &&
2876             reflectionData.redefinedCount == classRedefinedCount) {
2877             return reflectionData;

2878         }
2879         // else no SoftReference or cleared SoftReference or stale ReflectionData
2880         // -> create and replace new instance
2881         return newReflectionData(reflectionData, classRedefinedCount);
2882     }
2883 
2884     private ReflectionData<T> newReflectionData(ReflectionData<T> oldReflectionData,
2885                                                 int classRedefinedCount) {
2886         while (true) {
2887             ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2888             // try to CAS it...
2889             if (Atomic.casReflectionData(this, oldReflectionData, rd)) {
2890                 return rd;
2891             }
2892             // else retry
2893             oldReflectionData = this.reflectionData;
2894             classRedefinedCount = this.classRedefinedCount;
2895             if (oldReflectionData != null && oldReflectionData.redefinedCount == classRedefinedCount) {


2896                 return rd;
2897             }
2898         }
2899     }
2900 
2901     // Generic signature handling
2902     private native String getGenericSignature0();
2903 
2904     // Generic info repository; lazily initialized
2905     private transient volatile ClassRepository genericInfo;
2906 
2907     // accessor for factory
2908     private GenericsFactory getFactory() {
2909         // create scope and factory
2910         return CoreReflectionFactory.make(this, ClassScope.make(this));
2911     }
2912 
2913     // accessor for generic info repository;
2914     // generic info is lazily initialized
2915     private ClassRepository getGenericInfo() {

4172       * the original setting of ACC_SUPER.
4173       *
4174       * If this {@code Class} object represents a primitive type or
4175       * void, the flags are {@code PUBLIC}, {@code ABSTRACT}, and
4176       * {@code FINAL}.
4177       * If this {@code Class} object represents an array type, return 0.
4178       */
4179      int getClassFileAccessFlags() {
4180          return classFileAccessFlags;
4181      }
4182 
4183     // Validates the length of the class name and throws an exception if it exceeds the maximum allowed length.
4184     private static void validateClassNameLength(String name) throws ClassNotFoundException {
4185         if (!ModifiedUtf.isValidLengthInConstantPool(name)) {
4186             throw new ClassNotFoundException(
4187                     "Class name length exceeds limit of "
4188                     + ModifiedUtf.CONSTANT_POOL_UTF8_MAX_BYTES
4189                     + ": " + name.substring(0,256) + "...");
4190         }
4191     }
4192 
4193     // Support for "OLD" CDS workflow -- {
4194     private static final int RD_PUBLIC_METHODS          = (1 <<  0);
4195     private static final int RD_PUBLIC_FIELDS           = (1 <<  1);
4196     private static final int RD_DECLARED_CTORS          = (1 <<  2);
4197     private static final int RD_PUBLIC_CTORS = (1 <<  3);
4198     private static final int RD_DECLARED_METHODS        = (1 <<  4);
4199     private static final int RD_DECLARED_PUBLIC_METHODS = (1 <<  5);
4200     private static final int RD_DECLARED_FIELDS         = (1 <<  6);
4201     private static final int RD_DECLARED_PUBLIC_FIELDS  = (1 <<  7);
4202     private static final int RD_DECLARED_INTERFACES     = (1 <<  8);
4203     private static final int RD_DECLARED_SIMPLE_NAME    = (1 <<  9);
4204     private static final int RD_DECLARED_CANONICAL_NAME = (1 << 10);
4205     private static final int CLS_NAME = (1 << 10);
4206 
4207 
4208     private int encodeReflectionData() {
4209         int flags = CLS_NAME;
4210         if (reflectionData != null) {
4211             flags = (reflectionData.publicMethods         != null ? RD_PUBLIC_METHODS          : 0) |
4212                     (reflectionData.publicFields          != null ? RD_PUBLIC_FIELDS           : 0) |
4213                     (reflectionData.declaredConstructors  != null ? RD_DECLARED_CTORS          : 0) |
4214                     (reflectionData.publicConstructors    != null ? RD_PUBLIC_CTORS            : 0) |
4215                     (reflectionData.declaredMethods       != null ? RD_DECLARED_METHODS        : 0) |
4216                     (reflectionData.declaredPublicMethods != null ? RD_DECLARED_PUBLIC_METHODS : 0) |
4217                     (reflectionData.declaredFields        != null ? RD_DECLARED_FIELDS         : 0) |
4218                     (reflectionData.declaredPublicFields  != null ? RD_DECLARED_PUBLIC_FIELDS  : 0) |
4219                     (reflectionData.interfaces            != null ? RD_DECLARED_INTERFACES     : 0) |
4220                     (reflectionData.simpleName            != null ? RD_DECLARED_SIMPLE_NAME    : 0) |
4221                     (reflectionData.canonicalName         != null ? RD_DECLARED_CANONICAL_NAME : 0);
4222         }
4223         return flags;
4224     }
4225     private void generateReflectionData(int flags) {
4226         if ((flags & CLS_NAME                  ) != 0) { getName();                             } // String name
4227         if ((flags & RD_PUBLIC_METHODS         ) != 0) { privateGetPublicMethods();             } // Method[] publicMethods;
4228         if ((flags & RD_PUBLIC_FIELDS          ) != 0) { privateGetPublicFields();              } // Field[] publicFields;
4229         if ((flags & RD_DECLARED_CTORS         ) != 0) { privateGetDeclaredConstructors(false); } // Constructor<T>[] declaredConstructors;
4230         if ((flags & RD_PUBLIC_CTORS           ) != 0) { privateGetDeclaredConstructors(true);  } // Constructor<T>[] publicConstructors;
4231         if ((flags & RD_DECLARED_METHODS       ) != 0) { privateGetDeclaredMethods(false);      } // Method[] declaredMethods;
4232         if ((flags & RD_DECLARED_PUBLIC_METHODS) != 0) { privateGetDeclaredMethods(true);       } // Method[] declaredPublicMethods;
4233         if ((flags & RD_DECLARED_FIELDS        ) != 0) { privateGetDeclaredFields(false);       } // Field[] declaredFields;
4234         if ((flags & RD_DECLARED_PUBLIC_FIELDS ) != 0) { privateGetDeclaredFields(true);        } // Field[] declaredPublicFields;
4235         if ((flags & RD_DECLARED_INTERFACES    ) != 0) { getInterfaces(false);                  } // Class<?>[] interfaces;
4236         if ((flags & RD_DECLARED_SIMPLE_NAME   ) != 0) { getSimpleName();                       } // String simpleName;
4237         if ((flags & RD_DECLARED_CANONICAL_NAME) != 0) { getCanonicalName();                    } // String canonicalName;
4238     }
4239 
4240     // -- }
4241 }
< prev index next >