< prev index next >

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

Print this page
rev 58768 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: alanb, cjplummer, coleenp, dholmes, dlong, forax, jlahoda, psandoz, plevart, vromero
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com, jan.lahoda@oracle.com, amy.lu@oracle.com
rev 58769 : [mq]: type-descriptor-name


 146  * One nestmate acts as the
 147  * <em>nest host</em>, and enumerates the other nestmates which
 148  * belong to the nest; each of them in turn records it as the nest host.
 149  * The classes and interfaces which belong to a nest, including its host, are
 150  * determined when
 151  * {@code class} files are generated, for example, a Java compiler
 152  * will typically record a top-level class as the host of a nest where the
 153  * other members are the classes and interfaces whose declarations are
 154  * enclosed within the top-level class declaration.
 155  *
 156  * <p> A class or interface created by the invocation of
 157  * {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
 158  * Lookup::defineHiddenClass} is a {@linkplain Class#isHidden() <em>hidden</em>}
 159  * class or interface.
 160  * All kinds of class, including enum types and record types, may be
 161  * hidden classes; all kinds of interface, including annotation types,
 162  * may be hidden interfaces.
 163  *
 164  * The {@linkplain #getName() name of a hidden class or interface} is
 165  * not a <a href="ClassLoader.html#binary-name">binary name</a>,
 166  * which means that a hidden class or interface cannot be
 167  * referenced by the constant pools of other classes and interfaces,
 168  * and cannot be discovered by {@link #forName Class::forName} or
 169  * {@link ClassLoader#loadClass(String, boolean) ClassLoader::loadClass}.








 170  *
 171  * A hidden class or interface is never an array class, but may be
 172  * the element type of an array. In all other respects, the fact that
 173  * a class or interface is hidden has no bearing on the characteristics
 174  * exposed by the methods of class {@code Class}.
 175  *
 176  * @param <T> the type of the class modeled by this {@code Class}
 177  * object.  For example, the type of {@code String.class} is {@code
 178  * Class<String>}.  Use {@code Class<?>} if the class being modeled is
 179  * unknown.
 180  *
 181  * @author  unascribed
 182  * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
 183  * @since   1.0
 184  * @jls 15.8.2 Class Literals
 185  */
 186 public final class Class<T> implements java.io.Serializable,
 187                               GenericDeclaration,
 188                               Type,
 189                               AnnotatedElement,


1048      *
1049      * <p> If this class is a {@linkplain #isLocalClass local class} or an {@linkplain
1050      * #isAnonymousClass() anonymous class}, then this method is equivalent to
1051      * invoking {@code getPackageName()} on the {@linkplain #getDeclaringClass
1052      * declaring class} of the {@linkplain #getEnclosingMethod enclosing method} or
1053      * {@linkplain #getEnclosingConstructor enclosing constructor}.
1054      *
1055      * <p> If this class represents an array type then this method returns the
1056      * package name of the element type. If this class represents a primitive
1057      * type or void then the package name "{@code java.lang}" is returned.
1058      *
1059      * @return the fully qualified package name
1060      *
1061      * @since 9
1062      * @spec JPMS
1063      * @jls 6.7 Fully Qualified Names
1064      */
1065     public String getPackageName() {
1066         String pn = this.packageName;
1067         if (pn == null) {
1068             Class<?> c = this;
1069             while (c.isArray()) {
1070                 c = c.getComponentType();
1071             }
1072             if (c.isPrimitive()) {
1073                 pn = "java.lang";
1074             } else {
1075                 String cn = c.getName();
1076                 int dot = cn.lastIndexOf('.');
1077                 pn = (dot != -1) ? cn.substring(0, dot).intern() : "";
1078             }
1079             this.packageName = pn;
1080         }
1081         return pn;
1082     }
1083 
1084     // cached package name
1085     private transient String packageName;
1086 
1087     /**
1088      * Returns the interfaces directly implemented by the class or interface
1089      * represented by this {@code Class} object.
1090      *
1091      * <p>If this {@code Class} object represents a class, the return value is an array


1209      * Returns the {@code Class} representing the component type of an
1210      * array.  If this class does not represent an array class this method
1211      * returns null.
1212      *
1213      * @return the {@code Class} representing the component type of this
1214      * class if this class is an array
1215      * @see     java.lang.reflect.Array
1216      * @since 1.1
1217      */
1218     public Class<?> getComponentType() {
1219         // Only return for array types. Storage may be reused for Class for instance types.
1220         if (isArray()) {
1221             return componentType;
1222         } else {
1223             return null;
1224         }
1225     }
1226 
1227     private final Class<?> componentType;
1228 














1229 
1230     /**
1231      * Returns the Java language modifiers for this class or interface, encoded
1232      * in an integer. The modifiers consist of the Java Virtual Machine's
1233      * constants for {@code public}, {@code protected},
1234      * {@code private}, {@code final}, {@code static},
1235      * {@code abstract} and {@code interface}; they should be decoded
1236      * using the methods of class {@code Modifier}.
1237      *
1238      * <p> If the underlying class is an array class, then its
1239      * {@code public}, {@code private} and {@code protected}
1240      * modifiers are the same as those of its component type.  If this
1241      * {@code Class} object represents a primitive type or void, its
1242      * {@code public} modifier is always {@code true}, and its
1243      * {@code protected} and {@code private} modifiers are always
1244      * {@code false}. If this {@code Class} object represents an array class, a
1245      * primitive type or void, then its {@code final} modifier is always
1246      * {@code true} and its interface modifier is always
1247      * {@code false}. The values of its other modifiers are not determined
1248      * by this specification.


3006             String pkg = this.getPackageName();
3007             if (pkg != null && !pkg.isEmpty()) {
3008                 // skip the package access check on a proxy class in default proxy package
3009                 if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
3010                     sm.checkPackageAccess(pkg);
3011                 }
3012             }
3013         }
3014         // check package access on the proxy interfaces
3015         if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
3016             ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
3017         }
3018     }
3019 
3020     /**
3021      * Add a package name prefix if the name is not absolute Remove leading "/"
3022      * if name is absolute
3023      */
3024     private String resolveName(String name) {
3025         if (!name.startsWith("/")) {
3026             Class<?> c = this;
3027             while (c.isArray()) {
3028                 c = c.getComponentType();
3029             }
3030             String baseName = c.getPackageName();
3031             if (baseName != null && !baseName.isEmpty()) {
3032                 name = baseName.replace('.', '/') + "/" + name;
3033             }
3034         } else {
3035             name = name.substring(1);
3036         }
3037         return name;
3038     }
3039 
3040     /**
3041      * Atomic operations support.
3042      */
3043     private static class Atomic {
3044         // initialize Unsafe machinery here, since we need to call Class.class instance method
3045         // and have to avoid calling it in the static initializer of the Class class...
3046         private static final Unsafe unsafe = Unsafe.getUnsafe();
3047         // offset of Class.reflectionData instance field
3048         private static final long reflectionDataOffset
3049                 = unsafe.objectFieldOffset(Class.class, "reflectionData");


4224         if (isPrimitive() || isArray()) {
4225             return new Class<?>[] { this };
4226         }
4227         Class<?>[] members = getNestMembers0();
4228         // Can't actually enable this due to bootstrapping issues
4229         // assert(members.length != 1 || members[0] == this); // expected invariant from VM
4230 
4231         if (members.length > 1) {
4232             // If we return anything other than the current class we need
4233             // a security check
4234             SecurityManager sm = System.getSecurityManager();
4235             if (sm != null) {
4236                 checkPackageAccess(sm,
4237                                    ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
4238             }
4239         }
4240         return members;
4241     }
4242 
4243     /**
4244      * Returns the type descriptor string for this class.
4245      * <p>
4246      * Note that this is not a strict inverse of {@link #forName};












































4247      * distinct classes which share a common name but have different class loaders
4248      * will have identical descriptor strings.
4249      *
4250      * @return the type descriptor representation
4251      * @jvms 4.3.2 Field Descriptors
4252      * @since 12
4253      */
4254     @Override
4255     public String descriptorString() {
4256         if (isPrimitive())
4257             return Wrapper.forPrimitiveType(this).basicTypeString();
4258         else if (isArray()) {

4259             return "[" + componentType.descriptorString();
4260         }
4261         else {




4262             return "L" + getName().replace('.', '/') + ";";
4263         }
4264     }
4265 
4266     /**
4267      * Returns the component type of this {@code Class}, if it describes
4268      * an array type, or {@code null} otherwise.
4269      *
4270      * @implSpec
4271      * Equivalent to {@link Class#getComponentType()}.
4272      *
4273      * @return a {@code Class} describing the component type, or {@code null}
4274      * if this {@code Class} does not describe an array type
4275      * @since 12
4276      */
4277     @Override
4278     public Class<?> componentType() {
4279         return isArray() ? componentType : null;
4280     }
4281 


4284      * is described by this {@linkplain Class}.
4285      *
4286      * @return a {@code Class} describing the array type
4287      * @since 12
4288      */
4289     @Override
4290     public Class<?> arrayType() {
4291         return Array.newInstance(this, 0).getClass();
4292     }
4293 
4294     /**
4295      * Returns a nominal descriptor for this instance, if one can be
4296      * constructed, or an empty {@link Optional} if one cannot be.
4297      *
4298      * @return An {@link Optional} containing the resulting nominal descriptor,
4299      * or an empty {@link Optional} if one cannot be constructed.
4300      * @since 12
4301      */
4302     @Override
4303     public Optional<ClassDesc> describeConstable() {
4304         return Optional.of(ClassDesc.ofDescriptor(descriptorString()));


4305    }
4306 
4307     /**
4308      * Returns {@code true} if and only if the underlying class is a hidden class.
4309      *
4310      * @return {@code true} if and only if this class is a hidden class.
4311      *
4312      * @since 15
4313      * @see MethodHandles.Lookup#defineHiddenClass
4314      */
4315     @HotSpotIntrinsicCandidate
4316     public native boolean isHidden();
4317 
4318 }


 146  * One nestmate acts as the
 147  * <em>nest host</em>, and enumerates the other nestmates which
 148  * belong to the nest; each of them in turn records it as the nest host.
 149  * The classes and interfaces which belong to a nest, including its host, are
 150  * determined when
 151  * {@code class} files are generated, for example, a Java compiler
 152  * will typically record a top-level class as the host of a nest where the
 153  * other members are the classes and interfaces whose declarations are
 154  * enclosed within the top-level class declaration.
 155  *
 156  * <p> A class or interface created by the invocation of
 157  * {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
 158  * Lookup::defineHiddenClass} is a {@linkplain Class#isHidden() <em>hidden</em>}
 159  * class or interface.
 160  * All kinds of class, including enum types and record types, may be
 161  * hidden classes; all kinds of interface, including annotation types,
 162  * may be hidden interfaces.
 163  *
 164  * The {@linkplain #getName() name of a hidden class or interface} is
 165  * not a <a href="ClassLoader.html#binary-name">binary name</a>,
 166  * which means the following:
 167  * <ul>
 168  * <li>A hidden class or interface cannot be referenced by the constant pools
 169  *     of other classes and interfaces.
 170  * <li>A hidden class or interface cannot be described in
 171  *     {@linkplain java.lang.constant.ConstantDesc <em>nominal form</em>} by
 172  *     {@link #describeConstable() Class::describeConstable},
 173  *     {@link ClassDesc#of(String) ClassDesc::of}, or
 174  *     {@link ClassDesc#ofDescriptor(String) ClassDesc::ofDescriptor}.
 175  * <li>A hidden class or interface cannot be discovered by {@link #forName Class::forName}
 176  *     or {@link ClassLoader#loadClass(String, boolean) ClassLoader::loadClass}.
 177  * </ul>
 178  *
 179  * A hidden class or interface is never an array class, but may be
 180  * the element type of an array. In all other respects, the fact that
 181  * a class or interface is hidden has no bearing on the characteristics
 182  * exposed by the methods of class {@code Class}.
 183  *
 184  * @param <T> the type of the class modeled by this {@code Class}
 185  * object.  For example, the type of {@code String.class} is {@code
 186  * Class<String>}.  Use {@code Class<?>} if the class being modeled is
 187  * unknown.
 188  *
 189  * @author  unascribed
 190  * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
 191  * @since   1.0
 192  * @jls 15.8.2 Class Literals
 193  */
 194 public final class Class<T> implements java.io.Serializable,
 195                               GenericDeclaration,
 196                               Type,
 197                               AnnotatedElement,


1056      *
1057      * <p> If this class is a {@linkplain #isLocalClass local class} or an {@linkplain
1058      * #isAnonymousClass() anonymous class}, then this method is equivalent to
1059      * invoking {@code getPackageName()} on the {@linkplain #getDeclaringClass
1060      * declaring class} of the {@linkplain #getEnclosingMethod enclosing method} or
1061      * {@linkplain #getEnclosingConstructor enclosing constructor}.
1062      *
1063      * <p> If this class represents an array type then this method returns the
1064      * package name of the element type. If this class represents a primitive
1065      * type or void then the package name "{@code java.lang}" is returned.
1066      *
1067      * @return the fully qualified package name
1068      *
1069      * @since 9
1070      * @spec JPMS
1071      * @jls 6.7 Fully Qualified Names
1072      */
1073     public String getPackageName() {
1074         String pn = this.packageName;
1075         if (pn == null) {
1076             Class<?> c = isArray() ? elementType() : this;



1077             if (c.isPrimitive()) {
1078                 pn = "java.lang";
1079             } else {
1080                 String cn = c.getName();
1081                 int dot = cn.lastIndexOf('.');
1082                 pn = (dot != -1) ? cn.substring(0, dot).intern() : "";
1083             }
1084             this.packageName = pn;
1085         }
1086         return pn;
1087     }
1088 
1089     // cached package name
1090     private transient String packageName;
1091 
1092     /**
1093      * Returns the interfaces directly implemented by the class or interface
1094      * represented by this {@code Class} object.
1095      *
1096      * <p>If this {@code Class} object represents a class, the return value is an array


1214      * Returns the {@code Class} representing the component type of an
1215      * array.  If this class does not represent an array class this method
1216      * returns null.
1217      *
1218      * @return the {@code Class} representing the component type of this
1219      * class if this class is an array
1220      * @see     java.lang.reflect.Array
1221      * @since 1.1
1222      */
1223     public Class<?> getComponentType() {
1224         // Only return for array types. Storage may be reused for Class for instance types.
1225         if (isArray()) {
1226             return componentType;
1227         } else {
1228             return null;
1229         }
1230     }
1231 
1232     private final Class<?> componentType;
1233 
1234     /*
1235      * Returns the {@code Class} representing the element type of an array class.
1236      * If this class does not represent an array class, then this method returns
1237      * {@code null}.
1238      */
1239     private Class<?> elementType() {
1240         if (!isArray()) return null;
1241 
1242         Class<?> c = this;
1243         while (c.isArray()) {
1244             c = c.getComponentType();
1245         }
1246         return c;
1247     }
1248 
1249     /**
1250      * Returns the Java language modifiers for this class or interface, encoded
1251      * in an integer. The modifiers consist of the Java Virtual Machine's
1252      * constants for {@code public}, {@code protected},
1253      * {@code private}, {@code final}, {@code static},
1254      * {@code abstract} and {@code interface}; they should be decoded
1255      * using the methods of class {@code Modifier}.
1256      *
1257      * <p> If the underlying class is an array class, then its
1258      * {@code public}, {@code private} and {@code protected}
1259      * modifiers are the same as those of its component type.  If this
1260      * {@code Class} object represents a primitive type or void, its
1261      * {@code public} modifier is always {@code true}, and its
1262      * {@code protected} and {@code private} modifiers are always
1263      * {@code false}. If this {@code Class} object represents an array class, a
1264      * primitive type or void, then its {@code final} modifier is always
1265      * {@code true} and its interface modifier is always
1266      * {@code false}. The values of its other modifiers are not determined
1267      * by this specification.


3025             String pkg = this.getPackageName();
3026             if (pkg != null && !pkg.isEmpty()) {
3027                 // skip the package access check on a proxy class in default proxy package
3028                 if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
3029                     sm.checkPackageAccess(pkg);
3030                 }
3031             }
3032         }
3033         // check package access on the proxy interfaces
3034         if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
3035             ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
3036         }
3037     }
3038 
3039     /**
3040      * Add a package name prefix if the name is not absolute Remove leading "/"
3041      * if name is absolute
3042      */
3043     private String resolveName(String name) {
3044         if (!name.startsWith("/")) {
3045             Class<?> c = isArray() ? elementType() : this;



3046             String baseName = c.getPackageName();
3047             if (baseName != null && !baseName.isEmpty()) {
3048                 name = baseName.replace('.', '/') + "/" + name;
3049             }
3050         } else {
3051             name = name.substring(1);
3052         }
3053         return name;
3054     }
3055 
3056     /**
3057      * Atomic operations support.
3058      */
3059     private static class Atomic {
3060         // initialize Unsafe machinery here, since we need to call Class.class instance method
3061         // and have to avoid calling it in the static initializer of the Class class...
3062         private static final Unsafe unsafe = Unsafe.getUnsafe();
3063         // offset of Class.reflectionData instance field
3064         private static final long reflectionDataOffset
3065                 = unsafe.objectFieldOffset(Class.class, "reflectionData");


4240         if (isPrimitive() || isArray()) {
4241             return new Class<?>[] { this };
4242         }
4243         Class<?>[] members = getNestMembers0();
4244         // Can't actually enable this due to bootstrapping issues
4245         // assert(members.length != 1 || members[0] == this); // expected invariant from VM
4246 
4247         if (members.length > 1) {
4248             // If we return anything other than the current class we need
4249             // a security check
4250             SecurityManager sm = System.getSecurityManager();
4251             if (sm != null) {
4252                 checkPackageAccess(sm,
4253                                    ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
4254             }
4255         }
4256         return members;
4257     }
4258 
4259     /**
4260      * Returns the descriptor string of the entity (class, interface, array class,
4261      * primitive type, or {@code void}) represented by this {@code Class} object.
4262      *
4263      * <p> If this {@code Class} object represents a class or interface,
4264      * not an array class, then:
4265      * <ul>
4266      * <li> If the class or interface is not {@linkplain Class#isHidden() hidden},
4267      *      then the result is a field descriptor (JVMS {@jvms 4.3.2})
4268      *      for the class or interface. Calling
4269      *      {@link ClassDesc#ofDescriptor(String) ClassDesc::ofDescriptor}
4270      *      with the result descriptor string produces a {@link ClassDesc ClassDesc}
4271      *      describing this class or interface.
4272      * <li> If the class or interface is {@linkplain Class#isHidden() hidden},
4273      *      then the result is a string of the form:
4274      *      <blockquote>
4275      *      {@code "L" +} <em>N</em> {@code + "." + <suffix> + ";"}
4276      *      </blockquote>
4277      *      where <em>N</em> is the <a href="ClassLoader.html#binary-name">binary name</a>
4278      *      encoded in internal form indicated by the {@code class} file passed to
4279      *      {@link MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
4280      *      Lookup::defineHiddenClass}, and {@code <suffix>} is an unqualified name.
4281      *      A hidden class or interface has no {@linkplain ClassDesc nominal descriptor}.
4282      *      The result string is not a type descriptor.
4283      * </ul>
4284      *
4285      * <p> If this {@code Class} object represents an array class, then
4286      * the result is a string consisting of one or more '{@code [}' characters
4287      * representing the depth of the array nesting, followed by the
4288      * descriptor string of the element type.
4289      * <ul>
4290      * <li> If the element type is not a {@linkplain Class#isHidden() hidden} class
4291      * or interface, then this array class can be described nominally.
4292      * Calling {@link ClassDesc#ofDescriptor(String) ClassDesc::ofDescriptor}
4293      * with the result descriptor string produces a {@link ClassDesc ClassDesc}
4294      * describing this array class.
4295      * <li> If the element type is a {@linkplain Class#isHidden() hidden} class or
4296      * interface, then this array class cannot be described nominally.
4297      * The result string is not a type descriptor.
4298      * </ul>
4299      *
4300      * <p> If this {@code Class} object represents a primitive type or
4301      * {@code void}, then the result is a field descriptor string which
4302      * is a one-letter code corresponding to a primitive type or {@code void}
4303      * ({@code "B", "C", "D", "F", "I", "J", "S", "Z", "V"}) (JVMS {@jvms 4.3.2}).
4304      *
4305      * @apiNote
4306      * This is not a strict inverse of {@link #forName};
4307      * distinct classes which share a common name but have different class loaders
4308      * will have identical descriptor strings.
4309      *
4310      * @return the descriptor string for this {@code Class} object
4311      * @jvms 4.3.2 Field Descriptors
4312      * @since 12
4313      */
4314     @Override
4315     public String descriptorString() {
4316         if (isPrimitive())
4317             return Wrapper.forPrimitiveType(this).basicTypeString();
4318 
4319         if (isArray()) {
4320             return "[" + componentType.descriptorString();
4321         } else if (isHidden()) {
4322             String name = getName();
4323             int index = name.indexOf('/');
4324             return "L" + name.substring(0, index).replace('.', '/')
4325                        + "." + name.substring(index+1) + ";";
4326         } else {
4327             return "L" + getName().replace('.', '/') + ";";
4328         }
4329     }
4330 
4331     /**
4332      * Returns the component type of this {@code Class}, if it describes
4333      * an array type, or {@code null} otherwise.
4334      *
4335      * @implSpec
4336      * Equivalent to {@link Class#getComponentType()}.
4337      *
4338      * @return a {@code Class} describing the component type, or {@code null}
4339      * if this {@code Class} does not describe an array type
4340      * @since 12
4341      */
4342     @Override
4343     public Class<?> componentType() {
4344         return isArray() ? componentType : null;
4345     }
4346 


4349      * is described by this {@linkplain Class}.
4350      *
4351      * @return a {@code Class} describing the array type
4352      * @since 12
4353      */
4354     @Override
4355     public Class<?> arrayType() {
4356         return Array.newInstance(this, 0).getClass();
4357     }
4358 
4359     /**
4360      * Returns a nominal descriptor for this instance, if one can be
4361      * constructed, or an empty {@link Optional} if one cannot be.
4362      *
4363      * @return An {@link Optional} containing the resulting nominal descriptor,
4364      * or an empty {@link Optional} if one cannot be constructed.
4365      * @since 12
4366      */
4367     @Override
4368     public Optional<ClassDesc> describeConstable() {
4369         Class<?> c = isArray() ? elementType() : this;
4370         return c.isHidden() ? Optional.empty()
4371                             : Optional.of(ClassDesc.ofDescriptor(descriptorString()));
4372    }
4373 
4374     /**
4375      * Returns {@code true} if and only if the underlying class is a hidden class.
4376      *
4377      * @return {@code true} if and only if this class is a hidden class.
4378      *
4379      * @since 15
4380      * @see MethodHandles.Lookup#defineHiddenClass
4381      */
4382     @HotSpotIntrinsicCandidate
4383     public native boolean isHidden();
4384 
4385 }
< prev index next >