< prev index next >

src/java.base/share/classes/java/lang/Class.java

Print this page

 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         validateClassNameLength(className);
 471         ClassLoader loader = (caller == null) ? ClassLoader.getSystemClassLoader()
 472                                               : ClassLoader.getClassLoader(caller);













 473         return forName0(className, true, loader);
 474     }
 475 
 476     /**
 477      * Returns the {@code Class} object associated with the class or
 478      * interface with the given string name, using the given class loader.
 479      * Given the {@linkplain ClassLoader##binary-name binary name} for a class or interface,
 480      * this method attempts to locate and load the class or interface. The specified
 481      * class loader is used to load the class or interface.  If the parameter
 482      * {@code loader} is {@code null}, the class is loaded through the bootstrap
 483      * class loader.  The class is initialized only if the
 484      * {@code initialize} parameter is {@code true} and if it has
 485      * not been initialized earlier.
 486      *
 487      * <p> This method cannot be used to obtain any of the {@code Class} objects
 488      * representing primitive types or void, hidden classes or interfaces,
 489      * or array classes whose element type is a hidden class or interface.
 490      * If {@code name} denotes a primitive type or void, for example {@code I},
 491      * an attempt will be made to locate a user-defined class in the unnamed package
 492      * whose name is {@code I} instead.

 534      *
 535      * @throws    LinkageError if the linkage fails
 536      * @throws    ExceptionInInitializerError if the initialization provoked
 537      *            by this method fails
 538      * @throws    ClassNotFoundException if the class cannot be located by
 539      *            the specified class loader
 540      *
 541      * @see       java.lang.Class#forName(String)
 542      * @see       java.lang.ClassLoader
 543      *
 544      * @jls 12.2 Loading of Classes and Interfaces
 545      * @jls 12.3 Linking of Classes and Interfaces
 546      * @jls 12.4 Initialization of Classes and Interfaces
 547      * @jls 13.1 The Form of a Binary
 548      * @since     1.2
 549      */
 550     public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
 551         throws ClassNotFoundException
 552     {
 553         validateClassNameLength(name);
















 554         return forName0(name, initialize, loader);
 555     }
 556 
 557     /** Called after security check for system loader access checks have been made. */
 558     private static native Class<?> forName0(String name, boolean initialize,
 559                                             ClassLoader loader)
 560         throws ClassNotFoundException;
 561 
 562 
 563     /**
 564      * Returns the {@code Class} with the given {@linkplain ClassLoader##binary-name
 565      * binary name} in the given module.
 566      *
 567      * <p> This method attempts to locate and load the class or interface.
 568      * It does not link the class, and does not run the class initializer.
 569      * If the class is not found, this method returns {@code null}. </p>
 570      *
 571      * <p> If the class loader of the given module defines other modules and
 572      * the given name is a class defined in a different module, this method
 573      * returns {@code null} after the class is loaded. </p>

2751     }
2752 
2753     /**
2754      * Atomic operations support.
2755      */
2756     private static class Atomic {
2757         // initialize Unsafe machinery here, since we need to call Class.class instance method
2758         // and have to avoid calling it in the static initializer of the Class class...
2759         private static final Unsafe unsafe = Unsafe.getUnsafe();
2760         // offset of Class.reflectionData instance field
2761         private static final long reflectionDataOffset
2762                 = unsafe.objectFieldOffset(Class.class, "reflectionData");
2763         // offset of Class.annotationType instance field
2764         private static final long annotationTypeOffset
2765                 = unsafe.objectFieldOffset(Class.class, "annotationType");
2766         // offset of Class.annotationData instance field
2767         private static final long annotationDataOffset
2768                 = unsafe.objectFieldOffset(Class.class, "annotationData");
2769 
2770         static <T> boolean casReflectionData(Class<?> clazz,
2771                                              SoftReference<ReflectionData<T>> oldData,
2772                                              SoftReference<ReflectionData<T>> newData) {
2773             return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
2774         }
2775 
2776         static boolean casAnnotationType(Class<?> clazz,
2777                                          AnnotationType oldType,
2778                                          AnnotationType newType) {
2779             return unsafe.compareAndSetReference(clazz, annotationTypeOffset, oldType, newType);
2780         }
2781 
2782         static boolean casAnnotationData(Class<?> clazz,
2783                                          AnnotationData oldData,
2784                                          AnnotationData newData) {
2785             return unsafe.compareAndSetReference(clazz, annotationDataOffset, oldData, newData);
2786         }
2787     }
2788 
2789     /**
2790      * Reflection support.
2791      */
2792 

2800         volatile Constructor<T>[] declaredConstructors;
2801         volatile Constructor<T>[] publicConstructors;
2802         // Intermediate results for getFields and getMethods
2803         volatile Field[] declaredPublicFields;
2804         volatile Method[] declaredPublicMethods;
2805         volatile Class<?>[] interfaces;
2806 
2807         // Cached names
2808         String simpleName;
2809         String canonicalName;
2810         static final String NULL_SENTINEL = new String();
2811 
2812         // Value of classRedefinedCount when we created this ReflectionData instance
2813         final int redefinedCount;
2814 
2815         ReflectionData(int redefinedCount) {
2816             this.redefinedCount = redefinedCount;
2817         }
2818     }
2819 
2820     private transient volatile SoftReference<ReflectionData<T>> reflectionData;
2821 
2822     // Incremented by the VM on each call to JVM TI RedefineClasses()
2823     // that redefines this class or a superclass.
2824     private transient volatile int classRedefinedCount;
2825 
2826     // Lazily create and cache ReflectionData
2827     private ReflectionData<T> reflectionData() {
2828         SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2829         int classRedefinedCount = this.classRedefinedCount;
2830         ReflectionData<T> rd;
2831         if (reflectionData != null &&
2832             (rd = reflectionData.get()) != null &&
2833             rd.redefinedCount == classRedefinedCount) {
2834             return rd;
2835         }
2836         // else no SoftReference or cleared SoftReference or stale ReflectionData
2837         // -> create and replace new instance
2838         return newReflectionData(reflectionData, classRedefinedCount);
2839     }
2840 
2841     private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
2842                                                 int classRedefinedCount) {
2843         while (true) {
2844             ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2845             // try to CAS it...
2846             if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
2847                 return rd;
2848             }
2849             // else retry
2850             oldReflectionData = this.reflectionData;
2851             classRedefinedCount = this.classRedefinedCount;
2852             if (oldReflectionData != null &&
2853                 (rd = oldReflectionData.get()) != null &&
2854                 rd.redefinedCount == classRedefinedCount) {
2855                 return rd;
2856             }
2857         }
2858     }
2859 
2860     // Generic signature handling
2861     private native String getGenericSignature0();
2862 
2863     // Generic info repository; lazily initialized
2864     private transient volatile ClassRepository genericInfo;
2865 
2866     // accessor for factory
2867     private GenericsFactory getFactory() {
2868         // create scope and factory
2869         return CoreReflectionFactory.make(this, ClassScope.make(this));
2870     }
2871 
2872     // accessor for generic info repository;
2873     // generic info is lazily initialized
2874     private ClassRepository getGenericInfo() {

4131       * the original setting of ACC_SUPER.
4132       *
4133       * If this {@code Class} object represents a primitive type or
4134       * void, the flags are {@code PUBLIC}, {@code ABSTRACT}, and
4135       * {@code FINAL}.
4136       * If this {@code Class} object represents an array type, return 0.
4137       */
4138      int getClassFileAccessFlags() {
4139          return classFileAccessFlags;
4140      }
4141 
4142     // Validates the length of the class name and throws an exception if it exceeds the maximum allowed length.
4143     private static void validateClassNameLength(String name) throws ClassNotFoundException {
4144         if (!ModifiedUtf.isValidLengthInConstantPool(name)) {
4145             throw new ClassNotFoundException(
4146                     "Class name length exceeds limit of "
4147                     + ModifiedUtf.CONSTANT_POOL_UTF8_MAX_BYTES
4148                     + ": " + name.substring(0,256) + "...");
4149         }
4150     }

















































4151 }

 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         validateClassNameLength(className);
 471         ClassLoader loader = (caller == null) ? ClassLoader.getSystemClassLoader()
 472                                               : ClassLoader.getClassLoader(caller);
 473         if (loader instanceof BuiltinClassLoader bcl) {
 474             if (bcl.usePositiveCache) {
 475                 Class<?> result = bcl.checkPositiveLookupCache(className);
 476                 if (result != null) {
 477                     // forName(String, Class) API will always initialize the class
 478                     Unsafe.getUnsafe().ensureClassInitialized(result);
 479                     return result;
 480                 }
 481             }
 482             if (bcl.useNegativeCache && bcl.checkNegativeLookupCache(className)) {
 483                 throw new ClassNotFoundException(className);
 484             }
 485         }
 486         return forName0(className, true, loader);
 487     }
 488 
 489     /**
 490      * Returns the {@code Class} object associated with the class or
 491      * interface with the given string name, using the given class loader.
 492      * Given the {@linkplain ClassLoader##binary-name binary name} for a class or interface,
 493      * this method attempts to locate and load the class or interface. The specified
 494      * class loader is used to load the class or interface.  If the parameter
 495      * {@code loader} is {@code null}, the class is loaded through the bootstrap
 496      * class loader.  The class is initialized only if the
 497      * {@code initialize} parameter is {@code true} and if it has
 498      * not been initialized earlier.
 499      *
 500      * <p> This method cannot be used to obtain any of the {@code Class} objects
 501      * representing primitive types or void, hidden classes or interfaces,
 502      * or array classes whose element type is a hidden class or interface.
 503      * If {@code name} denotes a primitive type or void, for example {@code I},
 504      * an attempt will be made to locate a user-defined class in the unnamed package
 505      * whose name is {@code I} instead.

 547      *
 548      * @throws    LinkageError if the linkage fails
 549      * @throws    ExceptionInInitializerError if the initialization provoked
 550      *            by this method fails
 551      * @throws    ClassNotFoundException if the class cannot be located by
 552      *            the specified class loader
 553      *
 554      * @see       java.lang.Class#forName(String)
 555      * @see       java.lang.ClassLoader
 556      *
 557      * @jls 12.2 Loading of Classes and Interfaces
 558      * @jls 12.3 Linking of Classes and Interfaces
 559      * @jls 12.4 Initialization of Classes and Interfaces
 560      * @jls 13.1 The Form of a Binary
 561      * @since     1.2
 562      */
 563     public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
 564         throws ClassNotFoundException
 565     {
 566         validateClassNameLength(name);
 567 
 568         if (loader instanceof BuiltinClassLoader bcl) {
 569             if (bcl.usePositiveCache) {
 570                 Class<?> result = bcl.checkPositiveLookupCache(name);
 571                 if (result != null) {
 572                     if (initialize) {
 573                         Unsafe.getUnsafe().ensureClassInitialized(result);
 574                     }
 575                     return result;
 576                 }
 577             }
 578            if (bcl.useNegativeCache && bcl.checkNegativeLookupCache(name)) {
 579                 throw new ClassNotFoundException(name);
 580             }
 581         }
 582 
 583         return forName0(name, initialize, loader);
 584     }
 585 
 586     /** Called after security check for system loader access checks have been made. */
 587     private static native Class<?> forName0(String name, boolean initialize,
 588                                             ClassLoader loader)
 589         throws ClassNotFoundException;
 590 
 591 
 592     /**
 593      * Returns the {@code Class} with the given {@linkplain ClassLoader##binary-name
 594      * binary name} in the given module.
 595      *
 596      * <p> This method attempts to locate and load the class or interface.
 597      * It does not link the class, and does not run the class initializer.
 598      * If the class is not found, this method returns {@code null}. </p>
 599      *
 600      * <p> If the class loader of the given module defines other modules and
 601      * the given name is a class defined in a different module, this method
 602      * returns {@code null} after the class is loaded. </p>

2780     }
2781 
2782     /**
2783      * Atomic operations support.
2784      */
2785     private static class Atomic {
2786         // initialize Unsafe machinery here, since we need to call Class.class instance method
2787         // and have to avoid calling it in the static initializer of the Class class...
2788         private static final Unsafe unsafe = Unsafe.getUnsafe();
2789         // offset of Class.reflectionData instance field
2790         private static final long reflectionDataOffset
2791                 = unsafe.objectFieldOffset(Class.class, "reflectionData");
2792         // offset of Class.annotationType instance field
2793         private static final long annotationTypeOffset
2794                 = unsafe.objectFieldOffset(Class.class, "annotationType");
2795         // offset of Class.annotationData instance field
2796         private static final long annotationDataOffset
2797                 = unsafe.objectFieldOffset(Class.class, "annotationData");
2798 
2799         static <T> boolean casReflectionData(Class<?> clazz,
2800                                              ReflectionData<T> oldData,
2801                                              ReflectionData<T> newData) {
2802             return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
2803         }
2804 
2805         static boolean casAnnotationType(Class<?> clazz,
2806                                          AnnotationType oldType,
2807                                          AnnotationType newType) {
2808             return unsafe.compareAndSetReference(clazz, annotationTypeOffset, oldType, newType);
2809         }
2810 
2811         static boolean casAnnotationData(Class<?> clazz,
2812                                          AnnotationData oldData,
2813                                          AnnotationData newData) {
2814             return unsafe.compareAndSetReference(clazz, annotationDataOffset, oldData, newData);
2815         }
2816     }
2817 
2818     /**
2819      * Reflection support.
2820      */
2821 

2829         volatile Constructor<T>[] declaredConstructors;
2830         volatile Constructor<T>[] publicConstructors;
2831         // Intermediate results for getFields and getMethods
2832         volatile Field[] declaredPublicFields;
2833         volatile Method[] declaredPublicMethods;
2834         volatile Class<?>[] interfaces;
2835 
2836         // Cached names
2837         String simpleName;
2838         String canonicalName;
2839         static final String NULL_SENTINEL = new String();
2840 
2841         // Value of classRedefinedCount when we created this ReflectionData instance
2842         final int redefinedCount;
2843 
2844         ReflectionData(int redefinedCount) {
2845             this.redefinedCount = redefinedCount;
2846         }
2847     }
2848 
2849     private transient volatile ReflectionData<T> reflectionData;
2850 
2851     // Incremented by the VM on each call to JVM TI RedefineClasses()
2852     // that redefines this class or a superclass.
2853     private transient volatile int classRedefinedCount;
2854 
2855     // Lazily create and cache ReflectionData
2856     private ReflectionData<T> reflectionData() {
2857         ReflectionData<T> reflectionData = this.reflectionData;
2858         int classRedefinedCount = this.classRedefinedCount;

2859         if (reflectionData != null &&
2860             reflectionData.redefinedCount == classRedefinedCount) {
2861             return reflectionData;

2862         }
2863         // else no SoftReference or cleared SoftReference or stale ReflectionData
2864         // -> create and replace new instance
2865         return newReflectionData(reflectionData, classRedefinedCount);
2866     }
2867 
2868     private ReflectionData<T> newReflectionData(ReflectionData<T> oldReflectionData,
2869                                                 int classRedefinedCount) {
2870         while (true) {
2871             ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
2872             // try to CAS it...
2873             if (Atomic.casReflectionData(this, oldReflectionData, rd)) {
2874                 return rd;
2875             }
2876             // else retry
2877             oldReflectionData = this.reflectionData;
2878             classRedefinedCount = this.classRedefinedCount;
2879             if (oldReflectionData != null && oldReflectionData.redefinedCount == classRedefinedCount) {


2880                 return rd;
2881             }
2882         }
2883     }
2884 
2885     // Generic signature handling
2886     private native String getGenericSignature0();
2887 
2888     // Generic info repository; lazily initialized
2889     private transient volatile ClassRepository genericInfo;
2890 
2891     // accessor for factory
2892     private GenericsFactory getFactory() {
2893         // create scope and factory
2894         return CoreReflectionFactory.make(this, ClassScope.make(this));
2895     }
2896 
2897     // accessor for generic info repository;
2898     // generic info is lazily initialized
2899     private ClassRepository getGenericInfo() {

4156       * the original setting of ACC_SUPER.
4157       *
4158       * If this {@code Class} object represents a primitive type or
4159       * void, the flags are {@code PUBLIC}, {@code ABSTRACT}, and
4160       * {@code FINAL}.
4161       * If this {@code Class} object represents an array type, return 0.
4162       */
4163      int getClassFileAccessFlags() {
4164          return classFileAccessFlags;
4165      }
4166 
4167     // Validates the length of the class name and throws an exception if it exceeds the maximum allowed length.
4168     private static void validateClassNameLength(String name) throws ClassNotFoundException {
4169         if (!ModifiedUtf.isValidLengthInConstantPool(name)) {
4170             throw new ClassNotFoundException(
4171                     "Class name length exceeds limit of "
4172                     + ModifiedUtf.CONSTANT_POOL_UTF8_MAX_BYTES
4173                     + ": " + name.substring(0,256) + "...");
4174         }
4175     }
4176 
4177     // Support for "OLD" CDS workflow -- {
4178     private static final int RD_PUBLIC_METHODS          = (1 <<  0);
4179     private static final int RD_PUBLIC_FIELDS           = (1 <<  1);
4180     private static final int RD_DECLARED_CTORS          = (1 <<  2);
4181     private static final int RD_PUBLIC_CTORS = (1 <<  3);
4182     private static final int RD_DECLARED_METHODS        = (1 <<  4);
4183     private static final int RD_DECLARED_PUBLIC_METHODS = (1 <<  5);
4184     private static final int RD_DECLARED_FIELDS         = (1 <<  6);
4185     private static final int RD_DECLARED_PUBLIC_FIELDS  = (1 <<  7);
4186     private static final int RD_DECLARED_INTERFACES     = (1 <<  8);
4187     private static final int RD_DECLARED_SIMPLE_NAME    = (1 <<  9);
4188     private static final int RD_DECLARED_CANONICAL_NAME = (1 << 10);
4189     private static final int CLS_NAME = (1 << 10);
4190 
4191 
4192     private int encodeReflectionData() {
4193         int flags = CLS_NAME;
4194         if (reflectionData != null) {
4195             flags = (reflectionData.publicMethods         != null ? RD_PUBLIC_METHODS          : 0) |
4196                     (reflectionData.publicFields          != null ? RD_PUBLIC_FIELDS           : 0) |
4197                     (reflectionData.declaredConstructors  != null ? RD_DECLARED_CTORS          : 0) |
4198                     (reflectionData.publicConstructors    != null ? RD_PUBLIC_CTORS            : 0) |
4199                     (reflectionData.declaredMethods       != null ? RD_DECLARED_METHODS        : 0) |
4200                     (reflectionData.declaredPublicMethods != null ? RD_DECLARED_PUBLIC_METHODS : 0) |
4201                     (reflectionData.declaredFields        != null ? RD_DECLARED_FIELDS         : 0) |
4202                     (reflectionData.declaredPublicFields  != null ? RD_DECLARED_PUBLIC_FIELDS  : 0) |
4203                     (reflectionData.interfaces            != null ? RD_DECLARED_INTERFACES     : 0) |
4204                     (reflectionData.simpleName            != null ? RD_DECLARED_SIMPLE_NAME    : 0) |
4205                     (reflectionData.canonicalName         != null ? RD_DECLARED_CANONICAL_NAME : 0);
4206         }
4207         return flags;
4208     }
4209     private void generateReflectionData(int flags) {
4210         if ((flags & CLS_NAME                  ) != 0) { getName();                             } // String name
4211         if ((flags & RD_PUBLIC_METHODS         ) != 0) { privateGetPublicMethods();             } // Method[] publicMethods;
4212         if ((flags & RD_PUBLIC_FIELDS          ) != 0) { privateGetPublicFields();              } // Field[] publicFields;
4213         if ((flags & RD_DECLARED_CTORS         ) != 0) { privateGetDeclaredConstructors(false); } // Constructor<T>[] declaredConstructors;
4214         if ((flags & RD_PUBLIC_CTORS           ) != 0) { privateGetDeclaredConstructors(true);  } // Constructor<T>[] publicConstructors;
4215         if ((flags & RD_DECLARED_METHODS       ) != 0) { privateGetDeclaredMethods(false);      } // Method[] declaredMethods;
4216         if ((flags & RD_DECLARED_PUBLIC_METHODS) != 0) { privateGetDeclaredMethods(true);       } // Method[] declaredPublicMethods;
4217         if ((flags & RD_DECLARED_FIELDS        ) != 0) { privateGetDeclaredFields(false);       } // Field[] declaredFields;
4218         if ((flags & RD_DECLARED_PUBLIC_FIELDS ) != 0) { privateGetDeclaredFields(true);        } // Field[] declaredPublicFields;
4219         if ((flags & RD_DECLARED_INTERFACES    ) != 0) { getInterfaces(false);                  } // Class<?>[] interfaces;
4220         if ((flags & RD_DECLARED_SIMPLE_NAME   ) != 0) { getSimpleName();                       } // String simpleName;
4221         if ((flags & RD_DECLARED_CANONICAL_NAME) != 0) { getCanonicalName();                    } // String canonicalName;
4222     }
4223 
4224     // -- }
4225 }
< prev index next >