453 * @throws ClassNotFoundException if the class cannot be located
454 *
455 * @jls 12.2 Loading of Classes and Interfaces
456 * @jls 12.3 Linking of Classes and Interfaces
457 * @jls 12.4 Initialization of Classes and Interfaces
458 */
459 @CallerSensitive
460 public static Class<?> forName(String className)
461 throws ClassNotFoundException {
462 Class<?> caller = Reflection.getCallerClass();
463 return forName(className, caller);
464 }
465
466 // Caller-sensitive adapter method for reflective invocation
467 @CallerSensitiveAdapter
468 private static Class<?> forName(String className, Class<?> caller)
469 throws ClassNotFoundException {
470 validateClassNameLength(className);
471 ClassLoader loader = (caller == null) ? ClassLoader.getSystemClassLoader()
472 : ClassLoader.getClassLoader(caller);
473 return forName0(className, true, loader);
474 }
475
476 /**
477 * Returns the {@code Class} object associated with the class or
478 * interface with the given string name, using the given class loader.
479 * Given the {@linkplain ClassLoader##binary-name binary name} for a class or interface,
480 * this method attempts to locate and load the class or interface. The specified
481 * class loader is used to load the class or interface. If the parameter
482 * {@code loader} is {@code null}, the class is loaded through the bootstrap
483 * class loader. The class is initialized only if the
484 * {@code initialize} parameter is {@code true} and if it has
485 * not been initialized earlier.
486 *
487 * <p> This method cannot be used to obtain any of the {@code Class} objects
488 * representing primitive types or void, hidden classes or interfaces,
489 * or array classes whose element type is a hidden class or interface.
490 * If {@code name} denotes a primitive type or void, for example {@code I},
491 * an attempt will be made to locate a user-defined class in the unnamed package
492 * whose name is {@code I} instead.
534 *
535 * @throws LinkageError if the linkage fails
536 * @throws ExceptionInInitializerError if the initialization provoked
537 * by this method fails
538 * @throws ClassNotFoundException if the class cannot be located by
539 * the specified class loader
540 *
541 * @see java.lang.Class#forName(String)
542 * @see java.lang.ClassLoader
543 *
544 * @jls 12.2 Loading of Classes and Interfaces
545 * @jls 12.3 Linking of Classes and Interfaces
546 * @jls 12.4 Initialization of Classes and Interfaces
547 * @jls 13.1 The Form of a Binary
548 * @since 1.2
549 */
550 public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
551 throws ClassNotFoundException
552 {
553 validateClassNameLength(name);
554 return forName0(name, initialize, loader);
555 }
556
557 /** Called after security check for system loader access checks have been made. */
558 private static native Class<?> forName0(String name, boolean initialize,
559 ClassLoader loader)
560 throws ClassNotFoundException;
561
562
563 /**
564 * Returns the {@code Class} with the given {@linkplain ClassLoader##binary-name
565 * binary name} in the given module.
566 *
567 * <p> This method attempts to locate and load the class or interface.
568 * It does not link the class, and does not run the class initializer.
569 * If the class is not found, this method returns {@code null}. </p>
570 *
571 * <p> If the class loader of the given module defines other modules and
572 * the given name is a class defined in a different module, this method
573 * returns {@code null} after the class is loaded. </p>
2751 }
2752
2753 /**
2754 * Atomic operations support.
2755 */
2756 private static class Atomic {
2757 // initialize Unsafe machinery here, since we need to call Class.class instance method
2758 // and have to avoid calling it in the static initializer of the Class class...
2759 private static final Unsafe unsafe = Unsafe.getUnsafe();
2760 // offset of Class.reflectionData instance field
2761 private static final long reflectionDataOffset
2762 = unsafe.objectFieldOffset(Class.class, "reflectionData");
2763 // offset of Class.annotationType instance field
2764 private static final long annotationTypeOffset
2765 = unsafe.objectFieldOffset(Class.class, "annotationType");
2766 // offset of Class.annotationData instance field
2767 private static final long annotationDataOffset
2768 = unsafe.objectFieldOffset(Class.class, "annotationData");
2769
2770 static <T> boolean casReflectionData(Class<?> clazz,
2771 SoftReference<ReflectionData<T>> oldData,
2772 SoftReference<ReflectionData<T>> newData) {
2773 return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
2774 }
2775
2776 static boolean casAnnotationType(Class<?> clazz,
2777 AnnotationType oldType,
2778 AnnotationType newType) {
2779 return unsafe.compareAndSetReference(clazz, annotationTypeOffset, oldType, newType);
2780 }
2781
2782 static boolean casAnnotationData(Class<?> clazz,
2783 AnnotationData oldData,
2784 AnnotationData newData) {
2785 return unsafe.compareAndSetReference(clazz, annotationDataOffset, oldData, newData);
2786 }
2787 }
2788
2789 /**
2790 * Reflection support.
2791 */
2792
2800 volatile Constructor<T>[] declaredConstructors;
2801 volatile Constructor<T>[] publicConstructors;
2802 // Intermediate results for getFields and getMethods
2803 volatile Field[] declaredPublicFields;
2804 volatile Method[] declaredPublicMethods;
2805 volatile Class<?>[] interfaces;
2806
2807 // Cached names
2808 String simpleName;
2809 String canonicalName;
2810 static final String NULL_SENTINEL = new String();
2811
2812 // Value of classRedefinedCount when we created this ReflectionData instance
2813 final int redefinedCount;
2814
2815 ReflectionData(int redefinedCount) {
2816 this.redefinedCount = redefinedCount;
2817 }
2818 }
2819
2820 private transient volatile SoftReference<ReflectionData<T>> reflectionData;
2821
2822 // Incremented by the VM on each call to JVM TI RedefineClasses()
2823 // that redefines this class or a superclass.
2824 private transient volatile int classRedefinedCount;
2825
2826 // Lazily create and cache ReflectionData
2827 private ReflectionData<T> reflectionData() {
2828 SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2829 int classRedefinedCount = this.classRedefinedCount;
2830 ReflectionData<T> rd;
2831 if (reflectionData != null &&
2832 (rd = reflectionData.get()) != null &&
2833 rd.redefinedCount == classRedefinedCount) {
2834 return rd;
2835 }
2836 // else no SoftReference or cleared SoftReference or stale ReflectionData
2837 // -> create and replace new instance
2838 return newReflectionData(reflectionData, classRedefinedCount);
2839 }
2840
2841 private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
2842 int classRedefinedCount) {
2843 while (true) {
2844 ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2845 // try to CAS it...
2846 if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
2847 return rd;
2848 }
2849 // else retry
2850 oldReflectionData = this.reflectionData;
2851 classRedefinedCount = this.classRedefinedCount;
2852 if (oldReflectionData != null &&
2853 (rd = oldReflectionData.get()) != null &&
2854 rd.redefinedCount == classRedefinedCount) {
2855 return rd;
2856 }
2857 }
2858 }
2859
2860 // Generic signature handling
2861 private native String getGenericSignature0();
2862
2863 // Generic info repository; lazily initialized
2864 private transient volatile ClassRepository genericInfo;
2865
2866 // accessor for factory
2867 private GenericsFactory getFactory() {
2868 // create scope and factory
2869 return CoreReflectionFactory.make(this, ClassScope.make(this));
2870 }
2871
2872 // accessor for generic info repository;
2873 // generic info is lazily initialized
2874 private ClassRepository getGenericInfo() {
4131 * the original setting of ACC_SUPER.
4132 *
4133 * If this {@code Class} object represents a primitive type or
4134 * void, the flags are {@code PUBLIC}, {@code ABSTRACT}, and
4135 * {@code FINAL}.
4136 * If this {@code Class} object represents an array type, return 0.
4137 */
4138 int getClassFileAccessFlags() {
4139 return classFileAccessFlags;
4140 }
4141
4142 // Validates the length of the class name and throws an exception if it exceeds the maximum allowed length.
4143 private static void validateClassNameLength(String name) throws ClassNotFoundException {
4144 if (!ModifiedUtf.isValidLengthInConstantPool(name)) {
4145 throw new ClassNotFoundException(
4146 "Class name length exceeds limit of "
4147 + ModifiedUtf.CONSTANT_POOL_UTF8_MAX_BYTES
4148 + ": " + name.substring(0,256) + "...");
4149 }
4150 }
4151 }
|
453 * @throws ClassNotFoundException if the class cannot be located
454 *
455 * @jls 12.2 Loading of Classes and Interfaces
456 * @jls 12.3 Linking of Classes and Interfaces
457 * @jls 12.4 Initialization of Classes and Interfaces
458 */
459 @CallerSensitive
460 public static Class<?> forName(String className)
461 throws ClassNotFoundException {
462 Class<?> caller = Reflection.getCallerClass();
463 return forName(className, caller);
464 }
465
466 // Caller-sensitive adapter method for reflective invocation
467 @CallerSensitiveAdapter
468 private static Class<?> forName(String className, Class<?> caller)
469 throws ClassNotFoundException {
470 validateClassNameLength(className);
471 ClassLoader loader = (caller == null) ? ClassLoader.getSystemClassLoader()
472 : ClassLoader.getClassLoader(caller);
473 if (loader instanceof BuiltinClassLoader bcl) {
474 if (bcl.usePositiveCache) {
475 Class<?> result = bcl.checkPositiveLookupCache(className);
476 if (result != null) {
477 // forName(String, Class) API will always initialize the class
478 Unsafe.getUnsafe().ensureClassInitialized(result);
479 return result;
480 }
481 }
482 if (bcl.useNegativeCache && bcl.checkNegativeLookupCache(className)) {
483 throw new ClassNotFoundException(className);
484 }
485 }
486 return forName0(className, true, loader);
487 }
488
489 /**
490 * Returns the {@code Class} object associated with the class or
491 * interface with the given string name, using the given class loader.
492 * Given the {@linkplain ClassLoader##binary-name binary name} for a class or interface,
493 * this method attempts to locate and load the class or interface. The specified
494 * class loader is used to load the class or interface. If the parameter
495 * {@code loader} is {@code null}, the class is loaded through the bootstrap
496 * class loader. The class is initialized only if the
497 * {@code initialize} parameter is {@code true} and if it has
498 * not been initialized earlier.
499 *
500 * <p> This method cannot be used to obtain any of the {@code Class} objects
501 * representing primitive types or void, hidden classes or interfaces,
502 * or array classes whose element type is a hidden class or interface.
503 * If {@code name} denotes a primitive type or void, for example {@code I},
504 * an attempt will be made to locate a user-defined class in the unnamed package
505 * whose name is {@code I} instead.
547 *
548 * @throws LinkageError if the linkage fails
549 * @throws ExceptionInInitializerError if the initialization provoked
550 * by this method fails
551 * @throws ClassNotFoundException if the class cannot be located by
552 * the specified class loader
553 *
554 * @see java.lang.Class#forName(String)
555 * @see java.lang.ClassLoader
556 *
557 * @jls 12.2 Loading of Classes and Interfaces
558 * @jls 12.3 Linking of Classes and Interfaces
559 * @jls 12.4 Initialization of Classes and Interfaces
560 * @jls 13.1 The Form of a Binary
561 * @since 1.2
562 */
563 public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
564 throws ClassNotFoundException
565 {
566 validateClassNameLength(name);
567
568 if (loader instanceof BuiltinClassLoader bcl) {
569 if (bcl.usePositiveCache) {
570 Class<?> result = bcl.checkPositiveLookupCache(name);
571 if (result != null) {
572 if (initialize) {
573 Unsafe.getUnsafe().ensureClassInitialized(result);
574 }
575 return result;
576 }
577 }
578 if (bcl.useNegativeCache && bcl.checkNegativeLookupCache(name)) {
579 throw new ClassNotFoundException(name);
580 }
581 }
582
583 return forName0(name, initialize, loader);
584 }
585
586 /** Called after security check for system loader access checks have been made. */
587 private static native Class<?> forName0(String name, boolean initialize,
588 ClassLoader loader)
589 throws ClassNotFoundException;
590
591
592 /**
593 * Returns the {@code Class} with the given {@linkplain ClassLoader##binary-name
594 * binary name} in the given module.
595 *
596 * <p> This method attempts to locate and load the class or interface.
597 * It does not link the class, and does not run the class initializer.
598 * If the class is not found, this method returns {@code null}. </p>
599 *
600 * <p> If the class loader of the given module defines other modules and
601 * the given name is a class defined in a different module, this method
602 * returns {@code null} after the class is loaded. </p>
2780 }
2781
2782 /**
2783 * Atomic operations support.
2784 */
2785 private static class Atomic {
2786 // initialize Unsafe machinery here, since we need to call Class.class instance method
2787 // and have to avoid calling it in the static initializer of the Class class...
2788 private static final Unsafe unsafe = Unsafe.getUnsafe();
2789 // offset of Class.reflectionData instance field
2790 private static final long reflectionDataOffset
2791 = unsafe.objectFieldOffset(Class.class, "reflectionData");
2792 // offset of Class.annotationType instance field
2793 private static final long annotationTypeOffset
2794 = unsafe.objectFieldOffset(Class.class, "annotationType");
2795 // offset of Class.annotationData instance field
2796 private static final long annotationDataOffset
2797 = unsafe.objectFieldOffset(Class.class, "annotationData");
2798
2799 static <T> boolean casReflectionData(Class<?> clazz,
2800 ReflectionData<T> oldData,
2801 ReflectionData<T> newData) {
2802 return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
2803 }
2804
2805 static boolean casAnnotationType(Class<?> clazz,
2806 AnnotationType oldType,
2807 AnnotationType newType) {
2808 return unsafe.compareAndSetReference(clazz, annotationTypeOffset, oldType, newType);
2809 }
2810
2811 static boolean casAnnotationData(Class<?> clazz,
2812 AnnotationData oldData,
2813 AnnotationData newData) {
2814 return unsafe.compareAndSetReference(clazz, annotationDataOffset, oldData, newData);
2815 }
2816 }
2817
2818 /**
2819 * Reflection support.
2820 */
2821
2829 volatile Constructor<T>[] declaredConstructors;
2830 volatile Constructor<T>[] publicConstructors;
2831 // Intermediate results for getFields and getMethods
2832 volatile Field[] declaredPublicFields;
2833 volatile Method[] declaredPublicMethods;
2834 volatile Class<?>[] interfaces;
2835
2836 // Cached names
2837 String simpleName;
2838 String canonicalName;
2839 static final String NULL_SENTINEL = new String();
2840
2841 // Value of classRedefinedCount when we created this ReflectionData instance
2842 final int redefinedCount;
2843
2844 ReflectionData(int redefinedCount) {
2845 this.redefinedCount = redefinedCount;
2846 }
2847 }
2848
2849 private transient volatile ReflectionData<T> reflectionData;
2850
2851 // Incremented by the VM on each call to JVM TI RedefineClasses()
2852 // that redefines this class or a superclass.
2853 private transient volatile int classRedefinedCount;
2854
2855 // Lazily create and cache ReflectionData
2856 private ReflectionData<T> reflectionData() {
2857 ReflectionData<T> reflectionData = this.reflectionData;
2858 int classRedefinedCount = this.classRedefinedCount;
2859 if (reflectionData != null &&
2860 reflectionData.redefinedCount == classRedefinedCount) {
2861 return reflectionData;
2862 }
2863 // else no SoftReference or cleared SoftReference or stale ReflectionData
2864 // -> create and replace new instance
2865 return newReflectionData(reflectionData, classRedefinedCount);
2866 }
2867
2868 private ReflectionData<T> newReflectionData(ReflectionData<T> oldReflectionData,
2869 int classRedefinedCount) {
2870 while (true) {
2871 ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2872 // try to CAS it...
2873 if (Atomic.casReflectionData(this, oldReflectionData, rd)) {
2874 return rd;
2875 }
2876 // else retry
2877 oldReflectionData = this.reflectionData;
2878 classRedefinedCount = this.classRedefinedCount;
2879 if (oldReflectionData != null && oldReflectionData.redefinedCount == classRedefinedCount) {
2880 return rd;
2881 }
2882 }
2883 }
2884
2885 // Generic signature handling
2886 private native String getGenericSignature0();
2887
2888 // Generic info repository; lazily initialized
2889 private transient volatile ClassRepository genericInfo;
2890
2891 // accessor for factory
2892 private GenericsFactory getFactory() {
2893 // create scope and factory
2894 return CoreReflectionFactory.make(this, ClassScope.make(this));
2895 }
2896
2897 // accessor for generic info repository;
2898 // generic info is lazily initialized
2899 private ClassRepository getGenericInfo() {
4156 * the original setting of ACC_SUPER.
4157 *
4158 * If this {@code Class} object represents a primitive type or
4159 * void, the flags are {@code PUBLIC}, {@code ABSTRACT}, and
4160 * {@code FINAL}.
4161 * If this {@code Class} object represents an array type, return 0.
4162 */
4163 int getClassFileAccessFlags() {
4164 return classFileAccessFlags;
4165 }
4166
4167 // Validates the length of the class name and throws an exception if it exceeds the maximum allowed length.
4168 private static void validateClassNameLength(String name) throws ClassNotFoundException {
4169 if (!ModifiedUtf.isValidLengthInConstantPool(name)) {
4170 throw new ClassNotFoundException(
4171 "Class name length exceeds limit of "
4172 + ModifiedUtf.CONSTANT_POOL_UTF8_MAX_BYTES
4173 + ": " + name.substring(0,256) + "...");
4174 }
4175 }
4176
4177 // Support for "OLD" CDS workflow -- {
4178 private static final int RD_PUBLIC_METHODS = (1 << 0);
4179 private static final int RD_PUBLIC_FIELDS = (1 << 1);
4180 private static final int RD_DECLARED_CTORS = (1 << 2);
4181 private static final int RD_PUBLIC_CTORS = (1 << 3);
4182 private static final int RD_DECLARED_METHODS = (1 << 4);
4183 private static final int RD_DECLARED_PUBLIC_METHODS = (1 << 5);
4184 private static final int RD_DECLARED_FIELDS = (1 << 6);
4185 private static final int RD_DECLARED_PUBLIC_FIELDS = (1 << 7);
4186 private static final int RD_DECLARED_INTERFACES = (1 << 8);
4187 private static final int RD_DECLARED_SIMPLE_NAME = (1 << 9);
4188 private static final int RD_DECLARED_CANONICAL_NAME = (1 << 10);
4189 private static final int CLS_NAME = (1 << 10);
4190
4191
4192 private int encodeReflectionData() {
4193 int flags = CLS_NAME;
4194 if (reflectionData != null) {
4195 flags = (reflectionData.publicMethods != null ? RD_PUBLIC_METHODS : 0) |
4196 (reflectionData.publicFields != null ? RD_PUBLIC_FIELDS : 0) |
4197 (reflectionData.declaredConstructors != null ? RD_DECLARED_CTORS : 0) |
4198 (reflectionData.publicConstructors != null ? RD_PUBLIC_CTORS : 0) |
4199 (reflectionData.declaredMethods != null ? RD_DECLARED_METHODS : 0) |
4200 (reflectionData.declaredPublicMethods != null ? RD_DECLARED_PUBLIC_METHODS : 0) |
4201 (reflectionData.declaredFields != null ? RD_DECLARED_FIELDS : 0) |
4202 (reflectionData.declaredPublicFields != null ? RD_DECLARED_PUBLIC_FIELDS : 0) |
4203 (reflectionData.interfaces != null ? RD_DECLARED_INTERFACES : 0) |
4204 (reflectionData.simpleName != null ? RD_DECLARED_SIMPLE_NAME : 0) |
4205 (reflectionData.canonicalName != null ? RD_DECLARED_CANONICAL_NAME : 0);
4206 }
4207 return flags;
4208 }
4209 private void generateReflectionData(int flags) {
4210 if ((flags & CLS_NAME ) != 0) { getName(); } // String name
4211 if ((flags & RD_PUBLIC_METHODS ) != 0) { privateGetPublicMethods(); } // Method[] publicMethods;
4212 if ((flags & RD_PUBLIC_FIELDS ) != 0) { privateGetPublicFields(); } // Field[] publicFields;
4213 if ((flags & RD_DECLARED_CTORS ) != 0) { privateGetDeclaredConstructors(false); } // Constructor<T>[] declaredConstructors;
4214 if ((flags & RD_PUBLIC_CTORS ) != 0) { privateGetDeclaredConstructors(true); } // Constructor<T>[] publicConstructors;
4215 if ((flags & RD_DECLARED_METHODS ) != 0) { privateGetDeclaredMethods(false); } // Method[] declaredMethods;
4216 if ((flags & RD_DECLARED_PUBLIC_METHODS) != 0) { privateGetDeclaredMethods(true); } // Method[] declaredPublicMethods;
4217 if ((flags & RD_DECLARED_FIELDS ) != 0) { privateGetDeclaredFields(false); } // Field[] declaredFields;
4218 if ((flags & RD_DECLARED_PUBLIC_FIELDS ) != 0) { privateGetDeclaredFields(true); } // Field[] declaredPublicFields;
4219 if ((flags & RD_DECLARED_INTERFACES ) != 0) { getInterfaces(false); } // Class<?>[] interfaces;
4220 if ((flags & RD_DECLARED_SIMPLE_NAME ) != 0) { getSimpleName(); } // String simpleName;
4221 if ((flags & RD_DECLARED_CANONICAL_NAME) != 0) { getCanonicalName(); } // String canonicalName;
4222 }
4223
4224 // -- }
4225 }
|