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