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