< 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, caller);
 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, null);
 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                                             Class<?> caller)
 561         throws ClassNotFoundException;
 562 
 563 
 564     /**
 565      * Returns the {@code Class} with the given {@linkplain ClassLoader##binary-name
 566      * binary name} in the given module.
 567      *
 568      * <p> This method attempts to locate and load the class or interface.
 569      * It does not link the class, and does not run the class initializer.
 570      * If the class is not found, this method returns {@code null}. </p>
 571      *
 572      * <p> If the class loader of the given module defines other modules and
 573      * the given name is a class defined in a different module, this method

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

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

 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, caller);
 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, null);
 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                                             Class<?> caller)
 590         throws ClassNotFoundException;
 591 
 592 
 593     /**
 594      * Returns the {@code Class} with the given {@linkplain ClassLoader##binary-name
 595      * binary name} in the given module.
 596      *
 597      * <p> This method attempts to locate and load the class or interface.
 598      * It does not link the class, and does not run the class initializer.
 599      * If the class is not found, this method returns {@code null}. </p>
 600      *
 601      * <p> If the class loader of the given module defines other modules and
 602      * the given name is a class defined in a different module, this method

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

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

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

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


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