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