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
2755 }
2756
2757 /**
2758 * Atomic operations support.
2759 */
2760 private static class Atomic {
2761 // initialize Unsafe machinery here, since we need to call Class.class instance method
2762 // and have to avoid calling it in the static initializer of the Class class...
2763 private static final Unsafe unsafe = Unsafe.getUnsafe();
2764 // offset of Class.reflectionData instance field
2765 private static final long reflectionDataOffset
2766 = unsafe.objectFieldOffset(Class.class, "reflectionData");
2767 // offset of Class.annotationType instance field
2768 private static final long annotationTypeOffset
2769 = unsafe.objectFieldOffset(Class.class, "annotationType");
2770 // offset of Class.annotationData instance field
2771 private static final long annotationDataOffset
2772 = unsafe.objectFieldOffset(Class.class, "annotationData");
2773
2774 static <T> boolean casReflectionData(Class<?> clazz,
2775 SoftReference<ReflectionData<T>> oldData,
2776 SoftReference<ReflectionData<T>> newData) {
2777 return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
2778 }
2779
2780 static boolean casAnnotationType(Class<?> clazz,
2781 AnnotationType oldType,
2782 AnnotationType newType) {
2783 return unsafe.compareAndSetReference(clazz, annotationTypeOffset, oldType, newType);
2784 }
2785
2786 static boolean casAnnotationData(Class<?> clazz,
2787 AnnotationData oldData,
2788 AnnotationData newData) {
2789 return unsafe.compareAndSetReference(clazz, annotationDataOffset, oldData, newData);
2790 }
2791 }
2792
2793 /**
2794 * Reflection support.
2795 */
2796
2804 volatile Constructor<T>[] declaredConstructors;
2805 volatile Constructor<T>[] publicConstructors;
2806 // Intermediate results for getFields and getMethods
2807 volatile Field[] declaredPublicFields;
2808 volatile Method[] declaredPublicMethods;
2809 volatile Class<?>[] interfaces;
2810
2811 // Cached names
2812 String simpleName;
2813 String canonicalName;
2814 static final String NULL_SENTINEL = new String();
2815
2816 // Value of classRedefinedCount when we created this ReflectionData instance
2817 final int redefinedCount;
2818
2819 ReflectionData(int redefinedCount) {
2820 this.redefinedCount = redefinedCount;
2821 }
2822 }
2823
2824 private transient volatile SoftReference<ReflectionData<T>> reflectionData;
2825
2826 // Incremented by the VM on each call to JVM TI RedefineClasses()
2827 // that redefines this class or a superclass.
2828 private transient volatile int classRedefinedCount;
2829
2830 // Lazily create and cache ReflectionData
2831 private ReflectionData<T> reflectionData() {
2832 SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2833 int classRedefinedCount = this.classRedefinedCount;
2834 ReflectionData<T> rd;
2835 if (reflectionData != null &&
2836 (rd = reflectionData.get()) != null &&
2837 rd.redefinedCount == classRedefinedCount) {
2838 return rd;
2839 }
2840 // else no SoftReference or cleared SoftReference or stale ReflectionData
2841 // -> create and replace new instance
2842 return newReflectionData(reflectionData, classRedefinedCount);
2843 }
2844
2845 private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
2846 int classRedefinedCount) {
2847 while (true) {
2848 ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2849 // try to CAS it...
2850 if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
2851 return rd;
2852 }
2853 // else retry
2854 oldReflectionData = this.reflectionData;
2855 classRedefinedCount = this.classRedefinedCount;
2856 if (oldReflectionData != null &&
2857 (rd = oldReflectionData.get()) != null &&
2858 rd.redefinedCount == classRedefinedCount) {
2859 return rd;
2860 }
2861 }
2862 }
2863
2864 // Generic signature handling
2865 private native String getGenericSignature0();
2866
2867 // Generic info repository; lazily initialized
2868 private transient volatile ClassRepository genericInfo;
2869
2870 // accessor for factory
2871 private GenericsFactory getFactory() {
2872 // create scope and factory
2873 return CoreReflectionFactory.make(this, ClassScope.make(this));
2874 }
2875
2876 // accessor for generic info repository;
2877 // generic info is lazily initialized
2878 private ClassRepository getGenericInfo() {
4126 int getClassFileVersion() {
4127 Class<?> c = isArray() ? elementType() : this;
4128 return c.getClassFileVersion0();
4129 }
4130
4131 private native int getClassFileVersion0();
4132
4133 /*
4134 * Return the access flags as they were in the class's bytecode, including
4135 * the original setting of ACC_SUPER.
4136 *
4137 * If the class is an array type then the access flags of the element type is
4138 * returned. If the class is a primitive then ACC_ABSTRACT | ACC_FINAL | ACC_PUBLIC.
4139 */
4140 private int getClassAccessFlagsRaw() {
4141 Class<?> c = isArray() ? elementType() : this;
4142 return c.getClassAccessFlagsRaw0();
4143 }
4144
4145 private native int getClassAccessFlagsRaw0();
4146 }
|
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
2777 }
2778
2779 /**
2780 * Atomic operations support.
2781 */
2782 private static class Atomic {
2783 // initialize Unsafe machinery here, since we need to call Class.class instance method
2784 // and have to avoid calling it in the static initializer of the Class class...
2785 private static final Unsafe unsafe = Unsafe.getUnsafe();
2786 // offset of Class.reflectionData instance field
2787 private static final long reflectionDataOffset
2788 = unsafe.objectFieldOffset(Class.class, "reflectionData");
2789 // offset of Class.annotationType instance field
2790 private static final long annotationTypeOffset
2791 = unsafe.objectFieldOffset(Class.class, "annotationType");
2792 // offset of Class.annotationData instance field
2793 private static final long annotationDataOffset
2794 = unsafe.objectFieldOffset(Class.class, "annotationData");
2795
2796 static <T> boolean casReflectionData(Class<?> clazz,
2797 ReflectionData<T> oldData,
2798 ReflectionData<T> newData) {
2799 return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
2800 }
2801
2802 static boolean casAnnotationType(Class<?> clazz,
2803 AnnotationType oldType,
2804 AnnotationType newType) {
2805 return unsafe.compareAndSetReference(clazz, annotationTypeOffset, oldType, newType);
2806 }
2807
2808 static boolean casAnnotationData(Class<?> clazz,
2809 AnnotationData oldData,
2810 AnnotationData newData) {
2811 return unsafe.compareAndSetReference(clazz, annotationDataOffset, oldData, newData);
2812 }
2813 }
2814
2815 /**
2816 * Reflection support.
2817 */
2818
2826 volatile Constructor<T>[] declaredConstructors;
2827 volatile Constructor<T>[] publicConstructors;
2828 // Intermediate results for getFields and getMethods
2829 volatile Field[] declaredPublicFields;
2830 volatile Method[] declaredPublicMethods;
2831 volatile Class<?>[] interfaces;
2832
2833 // Cached names
2834 String simpleName;
2835 String canonicalName;
2836 static final String NULL_SENTINEL = new String();
2837
2838 // Value of classRedefinedCount when we created this ReflectionData instance
2839 final int redefinedCount;
2840
2841 ReflectionData(int redefinedCount) {
2842 this.redefinedCount = redefinedCount;
2843 }
2844 }
2845
2846 private transient volatile ReflectionData<T> reflectionData;
2847
2848 // Incremented by the VM on each call to JVM TI RedefineClasses()
2849 // that redefines this class or a superclass.
2850 private transient volatile int classRedefinedCount;
2851
2852 // Lazily create and cache ReflectionData
2853 private ReflectionData<T> reflectionData() {
2854 ReflectionData<T> reflectionData = this.reflectionData;
2855 int classRedefinedCount = this.classRedefinedCount;
2856 if (reflectionData != null &&
2857 reflectionData.redefinedCount == classRedefinedCount) {
2858 return reflectionData;
2859 }
2860 // else no SoftReference or cleared SoftReference or stale ReflectionData
2861 // -> create and replace new instance
2862 return newReflectionData(reflectionData, classRedefinedCount);
2863 }
2864
2865 private ReflectionData<T> newReflectionData(ReflectionData<T> oldReflectionData,
2866 int classRedefinedCount) {
2867 while (true) {
2868 ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2869 // try to CAS it...
2870 if (Atomic.casReflectionData(this, oldReflectionData, rd)) {
2871 return rd;
2872 }
2873 // else retry
2874 oldReflectionData = this.reflectionData;
2875 classRedefinedCount = this.classRedefinedCount;
2876 if (oldReflectionData != null && oldReflectionData.redefinedCount == classRedefinedCount) {
2877 return rd;
2878 }
2879 }
2880 }
2881
2882 // Generic signature handling
2883 private native String getGenericSignature0();
2884
2885 // Generic info repository; lazily initialized
2886 private transient volatile ClassRepository genericInfo;
2887
2888 // accessor for factory
2889 private GenericsFactory getFactory() {
2890 // create scope and factory
2891 return CoreReflectionFactory.make(this, ClassScope.make(this));
2892 }
2893
2894 // accessor for generic info repository;
2895 // generic info is lazily initialized
2896 private ClassRepository getGenericInfo() {
4144 int getClassFileVersion() {
4145 Class<?> c = isArray() ? elementType() : this;
4146 return c.getClassFileVersion0();
4147 }
4148
4149 private native int getClassFileVersion0();
4150
4151 /*
4152 * Return the access flags as they were in the class's bytecode, including
4153 * the original setting of ACC_SUPER.
4154 *
4155 * If the class is an array type then the access flags of the element type is
4156 * returned. If the class is a primitive then ACC_ABSTRACT | ACC_FINAL | ACC_PUBLIC.
4157 */
4158 private int getClassAccessFlagsRaw() {
4159 Class<?> c = isArray() ? elementType() : this;
4160 return c.getClassAccessFlagsRaw0();
4161 }
4162
4163 private native int getClassAccessFlagsRaw0();
4164
4165 // Support for "OLD" CDS workflow -- {
4166 private static final int RD_PUBLIC_METHODS = (1 << 0);
4167 private static final int RD_PUBLIC_FIELDS = (1 << 1);
4168 private static final int RD_DECLARED_CTORS = (1 << 2);
4169 private static final int RD_PUBLIC_CTORS = (1 << 3);
4170 private static final int RD_DECLARED_METHODS = (1 << 4);
4171 private static final int RD_DECLARED_PUBLIC_METHODS = (1 << 5);
4172 private static final int RD_DECLARED_FIELDS = (1 << 6);
4173 private static final int RD_DECLARED_PUBLIC_FIELDS = (1 << 7);
4174 private static final int RD_DECLARED_INTERFACES = (1 << 8);
4175 private static final int RD_DECLARED_SIMPLE_NAME = (1 << 9);
4176 private static final int RD_DECLARED_CANONICAL_NAME = (1 << 10);
4177 private static final int CLS_NAME = (1 << 10);
4178
4179
4180 private int encodeReflectionData() {
4181 int flags = CLS_NAME;
4182 if (reflectionData != null) {
4183 flags = (reflectionData.publicMethods != null ? RD_PUBLIC_METHODS : 0) |
4184 (reflectionData.publicFields != null ? RD_PUBLIC_FIELDS : 0) |
4185 (reflectionData.declaredConstructors != null ? RD_DECLARED_CTORS : 0) |
4186 (reflectionData.publicConstructors != null ? RD_PUBLIC_CTORS : 0) |
4187 (reflectionData.declaredMethods != null ? RD_DECLARED_METHODS : 0) |
4188 (reflectionData.declaredPublicMethods != null ? RD_DECLARED_PUBLIC_METHODS : 0) |
4189 (reflectionData.declaredFields != null ? RD_DECLARED_FIELDS : 0) |
4190 (reflectionData.declaredPublicFields != null ? RD_DECLARED_PUBLIC_FIELDS : 0) |
4191 (reflectionData.interfaces != null ? RD_DECLARED_INTERFACES : 0) |
4192 (reflectionData.simpleName != null ? RD_DECLARED_SIMPLE_NAME : 0) |
4193 (reflectionData.canonicalName != null ? RD_DECLARED_CANONICAL_NAME : 0);
4194 }
4195 return flags;
4196 }
4197 private void generateReflectionData(int flags) {
4198 if ((flags & CLS_NAME ) != 0) { getName(); } // String name
4199 if ((flags & RD_PUBLIC_METHODS ) != 0) { privateGetPublicMethods(); } // Method[] publicMethods;
4200 if ((flags & RD_PUBLIC_FIELDS ) != 0) { privateGetPublicFields(); } // Field[] publicFields;
4201 if ((flags & RD_DECLARED_CTORS ) != 0) { privateGetDeclaredConstructors(false); } // Constructor<T>[] declaredConstructors;
4202 if ((flags & RD_PUBLIC_CTORS ) != 0) { privateGetDeclaredConstructors(true); } // Constructor<T>[] publicConstructors;
4203 if ((flags & RD_DECLARED_METHODS ) != 0) { privateGetDeclaredMethods(false); } // Method[] declaredMethods;
4204 if ((flags & RD_DECLARED_PUBLIC_METHODS) != 0) { privateGetDeclaredMethods(true); } // Method[] declaredPublicMethods;
4205 if ((flags & RD_DECLARED_FIELDS ) != 0) { privateGetDeclaredFields(false); } // Field[] declaredFields;
4206 if ((flags & RD_DECLARED_PUBLIC_FIELDS ) != 0) { privateGetDeclaredFields(true); } // Field[] declaredPublicFields;
4207 if ((flags & RD_DECLARED_INTERFACES ) != 0) { getInterfaces(false); } // Class<?>[] interfaces;
4208 if ((flags & RD_DECLARED_SIMPLE_NAME ) != 0) { getSimpleName(); } // String simpleName;
4209 if ((flags & RD_DECLARED_CANONICAL_NAME) != 0) { getCanonicalName(); } // String canonicalName;
4210 }
4211
4212 // -- }
4213 }
|