< 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>

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 }
< prev index next >