< prev index next >

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

Print this page

 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>

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

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

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

















































4152 }

 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>

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

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

2864         if (reflectionData != null &&
2865             reflectionData.redefinedCount == classRedefinedCount) {
2866             return reflectionData;

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


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

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