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