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