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