< prev index next >
src/java.base/share/classes/java/lang/Class.java
Print this page
rev 58760 : 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
*** 26,35 ****
--- 26,36 ----
package java.lang;
import java.lang.annotation.Annotation;
import java.lang.constant.ClassDesc;
import java.lang.invoke.TypeDescriptor;
+ import java.lang.invoke.MethodHandles;
import java.lang.module.ModuleReader;
import java.lang.ref.SoftReference;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectStreamField;
*** 61,72 ****
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
- import java.util.StringJoiner;
- import java.util.stream.Stream;
import java.util.stream.Collectors;
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
--- 62,71 ----
*** 98,117 ****
* ({@code boolean}, {@code byte}, {@code char}, {@code short}, {@code
* int}, {@code long}, {@code float}, and {@code double}), and the
* keyword {@code void} are also represented as {@code Class} objects.
*
* <p> {@code Class} has no public constructor. Instead a {@code Class}
! * object is constructed automatically by the Java Virtual Machine
! * when a class loader invokes one of the
! * {@link ClassLoader#defineClass(String,byte[], int,int) defineClass} methods
! * and passes the bytes of a {@code class} file.
*
* <p> The methods of class {@code Class} expose many characteristics of a
* class or interface. Most characteristics are derived from the {@code class}
! * file that the class loader passed to the Java Virtual Machine. A few
! * characteristics are determined by the class loading environment at run time,
! * such as the module returned by {@link #getModule() getModule()}.
*
* <p> Some methods of class {@code Class} expose whether the declaration of
* a class or interface in Java source code was <em>enclosed</em> within
* another declaration. Other methods describe how a class or interface
* is situated in a <em>nest</em>. A <a id="nest">nest</a> is a set of
--- 97,142 ----
* ({@code boolean}, {@code byte}, {@code char}, {@code short}, {@code
* int}, {@code long}, {@code float}, and {@code double}), and the
* keyword {@code void} are also represented as {@code Class} objects.
*
* <p> {@code Class} has no public constructor. Instead a {@code Class}
! * object is constructed automatically by the Java Virtual Machine when
! * a class is derived from the bytes of a {@code class} file through
! * the invocation of one of the following methods:
! * <ul>
! * <li> {@link ClassLoader#defineClass(String, byte[], int, int) ClassLoader::defineClass}
! * <li> {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[])
! * java.lang.invoke.MethodHandles.Lookup::defineClass}
! * <li> {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
! * java.lang.invoke.MethodHandles.Lookup::defineHiddenClass}
! * </ul>
*
* <p> The methods of class {@code Class} expose many characteristics of a
* class or interface. Most characteristics are derived from the {@code class}
! * file that the class loader passed to the Java Virtual Machine or
! * from the {@code class} file passed to {@code Lookup::defineClass}
! * or {@code Lookup::defineHiddenClass}.
! * A few characteristics are determined by the class loading environment
! * at run time, such as the module returned by {@link #getModule() getModule()}.
! *
! * <p> The following example uses a {@code Class} object to print the
! * class name of an object:
! *
! * <blockquote><pre>
! * void printClassName(Object obj) {
! * System.out.println("The class of " + obj +
! * " is " + obj.getClass().getName());
! * }
! * </pre></blockquote>
! *
! * It is also possible to get the {@code Class} object for a named
! * type (or for {@code void}) using a <i>class literal</i>.
! * For example:
! *
! * <blockquote>
! * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
! * </blockquote>
*
* <p> Some methods of class {@code Class} expose whether the declaration of
* a class or interface in Java source code was <em>enclosed</em> within
* another declaration. Other methods describe how a class or interface
* is situated in a <em>nest</em>. A <a id="nest">nest</a> is a set of
*** 126,162 ****
* {@code class} files are generated, for example, a Java compiler
* will typically record a top-level class as the host of a nest where the
* other members are the classes and interfaces whose declarations are
* enclosed within the top-level class declaration.
*
! * <p> The following example uses a {@code Class} object to print the
! * class name of an object:
! *
! * <blockquote><pre>
! * void printClassName(Object obj) {
! * System.out.println("The class of " + obj +
! * " is " + obj.getClass().getName());
! * }
! * </pre></blockquote>
! *
! * <p> It is also possible to get the {@code Class} object for a named
! * type (or for void) using a class literal. See Section {@jls
! * 15.8.2} of <cite>The Java™ Language Specification</cite>.
! * For example:
! *
! * <blockquote>
! * {@code System.out.println("The name of class Foo is: " + Foo.class.getName());}
! * </blockquote>
*
* @param <T> the type of the class modeled by this {@code Class}
* object. For example, the type of {@code String.class} is {@code
* Class<String>}. Use {@code Class<?>} if the class being modeled is
* unknown.
*
* @author unascribed
* @see java.lang.ClassLoader#defineClass(byte[], int, int)
* @since 1.0
*/
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement,
--- 151,189 ----
* {@code class} files are generated, for example, a Java compiler
* will typically record a top-level class as the host of a nest where the
* other members are the classes and interfaces whose declarations are
* enclosed within the top-level class declaration.
*
! * <p> A class or interface created by the invocation of
! * {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
! * Lookup::defineHiddenClass} is a {@linkplain Class#isHidden() <em>hidden</em>}
! * class or interface.
! * All kinds of class, including enum types and record types, may be
! * hidden classes; all kinds of interface, including annotation types,
! * may be hidden interfaces.
! *
! * The {@linkplain #getName() name of a hidden class or interface} is
! * not a <a href="ClassLoader.html#binary-name">binary name</a>,
! * which means that a hidden class or interface cannot be
! * referenced by the constant pools of other classes and interfaces,
! * and cannot be discovered by {@link #forName Class::forName} or
! * {@link ClassLoader#loadClass(String, boolean) ClassLoader::loadClass}.
! *
! * A hidden class or interface is never an array class, but may be
! * the element type of an array. In all other respects, the fact that
! * a class or interface is hidden has no bearing on the characteristics
! * exposed by the methods of class {@code Class}.
*
* @param <T> the type of the class modeled by this {@code Class}
* object. For example, the type of {@code String.class} is {@code
* Class<String>}. Use {@code Class<?>} if the class being modeled is
* unknown.
*
* @author unascribed
* @see java.lang.ClassLoader#defineClass(byte[], int, int)
* @since 1.0
+ * @jls 15.8.2 Class Literals
*/
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement,
*** 184,196 ****
}
/**
* Converts the object to a string. The string representation is the
* string "class" or "interface", followed by a space, and then by the
! * fully qualified name of the class in the format returned by
! * {@code getName}. If this {@code Class} object represents a
! * primitive type, this method returns the name of the primitive type. If
* this {@code Class} object represents void this method returns
* "void". If this {@code Class} object represents an array type,
* this method returns "class " followed by {@code getName}.
*
* @return a string representation of this {@code Class} object.
--- 211,223 ----
}
/**
* Converts the object to a string. The string representation is the
* string "class" or "interface", followed by a space, and then by the
! * name of the class in the format returned by {@code getName}.
! * If this {@code Class} object represents a primitive type,
! * this method returns the name of the primitive type. If
* this {@code Class} object represents void this method returns
* "void". If this {@code Class} object represents an array type,
* this method returns "class " followed by {@code getName}.
*
* @return a string representation of this {@code Class} object.
*** 743,803 ****
public boolean isAnnotation() {
return (getModifiers() & ANNOTATION) != 0;
}
/**
! * Returns {@code true} if this class is a synthetic class;
! * returns {@code false} otherwise.
! * @return {@code true} if and only if this class is a synthetic class as
! * defined by <cite>The Java™ Language Specification</cite>.
* @jls 13.1 The Form of a Binary
* @since 1.5
*/
public boolean isSynthetic() {
return (getModifiers() & SYNTHETIC) != 0;
}
/**
* Returns the name of the entity (class, interface, array class,
! * primitive type, or void) represented by this {@code Class} object,
! * as a {@code String}.
*
! * <p> If this {@code Class} object represents a reference type that is
! * not an array type then the binary name of the class is
! * returned, as specified by <cite>The Java™ Language
! * Specification</cite>.
*
! * <p> If this {@code Class} object represents a primitive type or void, then the
! * name returned is a {@code String} equal to the Java language
! * keyword corresponding to the primitive type or void.
! *
! * <p> If this {@code Class} object represents a class of arrays, then the internal
! * form of the name consists of the name of the element type preceded by
! * one or more '{@code [}' characters representing the depth of the array
! * nesting. The encoding of element type names is as follows:
*
* <blockquote><table class="striped">
* <caption style="display:none">Element types and encodings</caption>
* <thead>
* <tr><th scope="col"> Element Type <th scope="col"> Encoding
* </thead>
* <tbody style="text-align:left">
! * <tr><th scope="row"> boolean <td style="text-align:center"> Z
! * <tr><th scope="row"> byte <td style="text-align:center"> B
! * <tr><th scope="row"> char <td style="text-align:center"> C
! * <tr><th scope="row"> class or interface
! * <td style="text-align:center"> L<i>classname</i>;
! * <tr><th scope="row"> double <td style="text-align:center"> D
! * <tr><th scope="row"> float <td style="text-align:center"> F
! * <tr><th scope="row"> int <td style="text-align:center"> I
! * <tr><th scope="row"> long <td style="text-align:center"> J
! * <tr><th scope="row"> short <td style="text-align:center"> S
* </tbody>
* </table></blockquote>
*
! * <p> The class or interface name <i>classname</i> is the binary name of
! * the class specified above.
*
* <p> Examples:
* <blockquote><pre>
* String.class.getName()
* returns "java.lang.String"
--- 770,836 ----
public boolean isAnnotation() {
return (getModifiers() & ANNOTATION) != 0;
}
/**
! * Returns {@code true} if and only if this class has the synthetic modifier
! * bit set.
! *
! * @return {@code true} if and only if this class has the synthetic modifier bit set
* @jls 13.1 The Form of a Binary
+ * @jvms 4.1 The {@code ClassFile} Structure
* @since 1.5
*/
public boolean isSynthetic() {
return (getModifiers() & SYNTHETIC) != 0;
}
/**
* Returns the name of the entity (class, interface, array class,
! * primitive type, or void) represented by this {@code Class} object.
*
! * <p> If this {@code Class} object represents a class or interface,
! * not an array class, then:
! * <ul>
! * <li> If the class or interface is not {@linkplain #isHidden() hidden},
! * then the <a href="ClassLoader.html#binary-name">binary name</a>
! * of the class or interface is returned.
! * <li> If the class or interface is hidden, then the result is a string
! * of the form: {@code N + '/' + <suffix>}
! * where {@code N} is the <a href="ClassLoader.html#binary-name">binary name</a>
! * indicated by the {@code class} file passed to
! * {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
! * Lookup::defineHiddenClass}, and {@code <suffix>} is an unqualified name.
! * </ul>
*
! * <p> If this {@code Class} object represents an array class, then
! * the result is a string consisting of one or more '{@code [}' characters
! * representing the depth of the array nesting, followed by the element
! * type as encoded using the following table:
*
* <blockquote><table class="striped">
* <caption style="display:none">Element types and encodings</caption>
* <thead>
* <tr><th scope="col"> Element Type <th scope="col"> Encoding
* </thead>
* <tbody style="text-align:left">
! * <tr><th scope="row"> {@code boolean} <td style="text-align:center"> {@code Z}
! * <tr><th scope="row"> {@code byte} <td style="text-align:center"> {@code B}
! * <tr><th scope="row"> {@code char} <td style="text-align:center"> {@code C}
! * <tr><th scope="row"> class or interface with <a href="ClassLoader.html#binary-name">binary name</a> <i>N</i>
! * <td style="text-align:center"> {@code L}<em>N</em>{@code ;}
! * <tr><th scope="row"> {@code double} <td style="text-align:center"> {@code D}
! * <tr><th scope="row"> {@code float} <td style="text-align:center"> {@code F}
! * <tr><th scope="row"> {@code int} <td style="text-align:center"> {@code I}
! * <tr><th scope="row"> {@code long} <td style="text-align:center"> {@code J}
! * <tr><th scope="row"> {@code short} <td style="text-align:center"> {@code S}
* </tbody>
* </table></blockquote>
*
! * <p> If this {@code Class} object represents a primitive type or {@code void},
! * then the result is a string with the same spelling as the Java language
! * keyword which corresponds to the primitive type or {@code void}.
*
* <p> Examples:
* <blockquote><pre>
* String.class.getName()
* returns "java.lang.String"
*** 807,818 ****
* returns "[Ljava.lang.Object;"
* (new int[3][4][5][6][7][8][9]).getClass().getName()
* returns "[[[[[[[I"
* </pre></blockquote>
*
! * @return the name of the class or interface
* represented by this {@code Class} object.
*/
public String getName() {
String name = this.name;
return name != null ? name : initClassName();
}
--- 840,852 ----
* returns "[Ljava.lang.Object;"
* (new int[3][4][5][6][7][8][9]).getClass().getName()
* returns "[[[[[[[I"
* </pre></blockquote>
*
! * @return the name of the class, interface, or other entity
* represented by this {@code Class} object.
+ * @jls 13.1 The Form of a Binary
*/
public String getName() {
String name = this.name;
return name != null ? name : initClassName();
}
*** 886,895 ****
--- 920,937 ----
// Initialized in JVM not by private constructor
// This field is filtered from reflection access, i.e. getDeclaredField
// will throw NoSuchFieldException
private final ClassLoader classLoader;
+ // Set by VM
+ private transient Object classData;
+
+ // package-private
+ Object getClassData() {
+ return classData;
+ }
+
/**
* Returns an array of {@code TypeVariable} objects that represent the
* type variables declared by the generic declaration represented by this
* {@code GenericDeclaration} object, in declaration order. Returns an
* array of length 0 if the underlying generic declaration declares no type
*** 898,908 ****
* @return an array of {@code TypeVariable} objects that represent
* the type variables declared by this generic declaration
* @throws java.lang.reflect.GenericSignatureFormatError if the generic
* signature of this generic declaration does not conform to
* the format specified in section {@jvms 4.7.9} of
! * <cite>The Java™ Virtual Machine Specification</cite>,
* @since 1.5
*/
@SuppressWarnings("unchecked")
public TypeVariable<Class<T>>[] getTypeParameters() {
ClassRepository info = getGenericInfo();
--- 940,950 ----
* @return an array of {@code TypeVariable} objects that represent
* the type variables declared by this generic declaration
* @throws java.lang.reflect.GenericSignatureFormatError if the generic
* signature of this generic declaration does not conform to
* the format specified in section {@jvms 4.7.9} of
! * <cite>The Java™ Virtual Machine Specification</cite>
* @since 1.5
*/
@SuppressWarnings("unchecked")
public TypeVariable<Class<T>>[] getTypeParameters() {
ClassRepository info = getGenericInfo();
*** 1612,1626 ****
}
return getName();
}
/**
! * Returns the canonical name of the underlying class as defined
! * by <cite>The Java™ Language Specification</cite>, section
! * {@jls 6.7}. Returns null if the underlying class does not have
! * a canonical name (i.e., if it is a local or anonymous class or
! * an array whose component type does not have a canonical name).
* @return the canonical name of the underlying class if it exists, and
* {@code null} otherwise.
* @since 1.5
*/
public String getCanonicalName() {
--- 1654,1674 ----
}
return getName();
}
/**
! * Returns the canonical name of the underlying class as
! * defined by <cite>The Java™ Language Specification</cite>.
! * Returns {@code null} if the underlying class does not have a canonical
! * name. Classes without canonical names include:
! * <ul>
! * <li>a {@linkplain #isLocalClass() local class}
! * <li>a {@linkplain #isAnonymousClass() anonymous class}
! * <li>a {@linkplain #isHidden() hidden class}
! * <li>an array whose component type does not have a canonical name</li>
! * </ul>
! *
* @return the canonical name of the underlying class if it exists, and
* {@code null} otherwise.
* @since 1.5
*/
public String getCanonicalName() {
*** 1638,1648 ****
if (canonicalName != null)
return canonicalName + "[]";
else
return ReflectionData.NULL_SENTINEL;
}
! if (isLocalOrAnonymousClass())
return ReflectionData.NULL_SENTINEL;
Class<?> enclosingClass = getEnclosingClass();
if (enclosingClass == null) { // top level class
return getName();
} else {
--- 1686,1696 ----
if (canonicalName != null)
return canonicalName + "[]";
else
return ReflectionData.NULL_SENTINEL;
}
! if (isHidden() || isLocalOrAnonymousClass())
return ReflectionData.NULL_SENTINEL;
Class<?> enclosingClass = getEnclosingClass();
if (enclosingClass == null) { // top level class
return getName();
} else {
*** 1655,1664 ****
--- 1703,1715 ----
/**
* Returns {@code true} if and only if the underlying class
* is an anonymous class.
*
+ * @apiNote
+ * An anonymous class is not a {@linkplain #isHidden() hidden class}.
+ *
* @return {@code true} if and only if this class is an anonymous class.
* @since 1.5
*/
public boolean isAnonymousClass() {
return !isArray() && isLocalOrAnonymousClass() &&
*** 2880,2889 ****
--- 2931,2945 ----
public java.security.ProtectionDomain getProtectionDomain() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
}
+ return protectionDomain();
+ }
+
+ // package-private
+ java.security.ProtectionDomain protectionDomain() {
java.security.ProtectionDomain pd = getProtectionDomain0();
if (pd == null) {
if (allPermDomain == null) {
java.security.Permissions perms =
new java.security.Permissions();
*** 2894,2904 ****
pd = allPermDomain;
}
return pd;
}
-
/**
* Returns the ProtectionDomain of this class.
*/
private native java.security.ProtectionDomain getProtectionDomain0();
--- 2950,2959 ----
*** 4013,4045 ****
private native Class<?> getNestHost0();
/**
* Returns the nest host of the <a href=#nest>nest</a> to which the class
* or interface represented by this {@code Class} object belongs.
! * Every class and interface is a member of exactly one nest.
! * A class or interface that is not recorded as belonging to a nest
! * belongs to the nest consisting only of itself, and is the nest
! * host.
! *
! * <p>Each of the {@code Class} objects representing array types,
! * primitive types, and {@code void} returns {@code this} to indicate
! * that the represented entity belongs to the nest consisting only of
! * itself, and is the nest host.
*
! * <p>If there is a {@linkplain LinkageError linkage error} accessing
! * the nest host, or if this class or interface is not enumerated as
! * a member of the nest by the nest host, then it is considered to belong
! * to its own nest and {@code this} is returned as the host.
! *
! * @apiNote A {@code class} file of version 55.0 or greater may record the
! * host of the nest to which it belongs by using the {@code NestHost}
! * attribute (JVMS {@jvms 4.7.28}). Alternatively, a {@code class} file of
! * version 55.0 or greater may act as a nest host by enumerating the nest's
! * other members with the
! * {@code NestMembers} attribute (JVMS {@jvms 4.7.29}).
! * A {@code class} file of version 54.0 or lower does not use these
! * attributes.
*
* @return the nest host of this class or interface
*
* @throws SecurityException
* If the returned class is not the current class, and
--- 4068,4093 ----
private native Class<?> getNestHost0();
/**
* Returns the nest host of the <a href=#nest>nest</a> to which the class
* or interface represented by this {@code Class} object belongs.
! * Every class and interface belongs to exactly one nest.
*
! * If the nest host of this class or interface has previously
! * been determined, then this method returns the nest host.
! * If the nest host of this class or interface has
! * not previously been determined, then this method determines the nest
! * host using the algorithm of JVMS 5.4.4, and returns it.
! *
! * Often, a class or interface belongs to a nest consisting only of itself,
! * in which case this method returns {@code this} to indicate that the class
! * or interface is the nest host.
! *
! * <p>If this {@code Class} object represents a primitive type, an array type,
! * or {@code void}, then this method returns {@code this},
! * indicating that the represented entity belongs to the nest consisting only of
! * itself, and is the nest host.
*
* @return the nest host of this class or interface
*
* @throws SecurityException
* If the returned class is not the current class, and
*** 4056,4076 ****
@CallerSensitive
public Class<?> getNestHost() {
if (isPrimitive() || isArray()) {
return this;
}
! Class<?> host;
! try {
! host = getNestHost0();
! } catch (LinkageError e) {
! // if we couldn't load our nest-host then we
! // act as-if we have no nest-host attribute
! return this;
! }
! // if null then nest membership validation failed, so we
! // act as-if we have no nest-host attribute
! if (host == null || host == this) {
return this;
}
// returning a different class requires a security check
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
--- 4104,4116 ----
@CallerSensitive
public Class<?> getNestHost() {
if (isPrimitive() || isArray()) {
return this;
}
!
! Class<?> host = getNestHost0();
! if (host == this) {
return this;
}
// returning a different class requires a security check
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
*** 4098,4153 ****
}
if (isPrimitive() || isArray() ||
c.isPrimitive() || c.isArray()) {
return false;
}
! try {
! return getNestHost0() == c.getNestHost0();
! } catch (LinkageError e) {
! return false;
! }
}
private native Class<?>[] getNestMembers0();
/**
* Returns an array containing {@code Class} objects representing all the
* classes and interfaces that are members of the nest to which the class
* or interface represented by this {@code Class} object belongs.
- * The {@linkplain #getNestHost() nest host} of that nest is the zeroth
- * element of the array. Subsequent elements represent any classes or
- * interfaces that are recorded by the nest host as being members of
- * the nest; the order of such elements is unspecified. Duplicates are
- * permitted.
- * If the nest host of that nest does not enumerate any members, then the
- * array has a single element containing {@code this}.
*
! * <p>Each of the {@code Class} objects representing array types,
! * primitive types, and {@code void} returns an array containing only
* {@code this}.
*
! * <p>This method validates that, for each class or interface which is
! * recorded as a member of the nest by the nest host, that class or
! * interface records itself as a member of that same nest. Any exceptions
! * that occur during this validation are rethrown by this method.
*
* @return an array of all classes and interfaces in the same nest as
! * this class
*
- * @throws LinkageError
- * If there is any problem loading or validating a nest member or
- * its nest host
* @throws SecurityException
* If any returned class is not the current class, and
* if a security manager, <i>s</i>, is present and the caller's
* class loader is not the same as or an ancestor of the class
* loader for that returned class and invocation of {@link
* SecurityManager#checkPackageAccess s.checkPackageAccess()}
* denies access to the package of that returned class
*
* @since 11
* @see #getNestHost()
*/
@CallerSensitive
public Class<?>[] getNestMembers() {
if (isPrimitive() || isArray()) {
return new Class<?>[] { this };
--- 4138,4198 ----
}
if (isPrimitive() || isArray() ||
c.isPrimitive() || c.isArray()) {
return false;
}
!
! return getNestHost() == c.getNestHost();
}
private native Class<?>[] getNestMembers0();
/**
* Returns an array containing {@code Class} objects representing all the
* classes and interfaces that are members of the nest to which the class
* or interface represented by this {@code Class} object belongs.
*
! * First, this method obtains the {@linkplain #getNestHost() nest host},
! * {@code H}, of the nest to which the class or interface represented by
! * this {@code Class} object belongs. The zeroth element of the returned
! * array is {@code H}.
! *
! * Then, for each class or interface {@code C} which is recorded by {@code H}
! * as being a member of its nest, this method attempts to obtain the {@code Class}
! * object for {@code C} (using {@linkplain #getClassLoader() the defining class
! * loader} of the current {@code Class} object), and then obtains the
! * {@linkplain #getNestHost() nest host} of the nest to which {@code C} belongs.
! * The classes and interfaces which are recorded by {@code H} as being members
! * of its nest, and for which {@code H} can be determined as their nest host,
! * are indicated by subsequent elements of the returned array. The order of
! * such elements is unspecified. Duplicates are permitted.
! *
! * <p>If this {@code Class} object represents a primitive type, an array type,
! * or {@code void}, then this method returns a single-element array containing
* {@code this}.
*
! * @apiNote
! * The returned array includes only the nest members recorded in the {@code NestMembers}
! * attribute, and not any hidden classes that were added to the nest via
! * {@link MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
! * Lookup::defineHiddenClass}.
*
* @return an array of all classes and interfaces in the same nest as
! * this class or interface
*
* @throws SecurityException
* If any returned class is not the current class, and
* if a security manager, <i>s</i>, is present and the caller's
* class loader is not the same as or an ancestor of the class
* loader for that returned class and invocation of {@link
* SecurityManager#checkPackageAccess s.checkPackageAccess()}
* denies access to the package of that returned class
*
* @since 11
* @see #getNestHost()
+ * @jvms 4.7.28 The {@code NestHost} Attribute
+ * @jvms 4.7.29 The {@code NestMembers} Attribute
*/
@CallerSensitive
public Class<?>[] getNestMembers() {
if (isPrimitive() || isArray()) {
return new Class<?>[] { this };
*** 4229,4234 ****
--- 4274,4291 ----
*/
@Override
public Optional<ClassDesc> describeConstable() {
return Optional.of(ClassDesc.ofDescriptor(descriptorString()));
}
+
+ /**
+ * Returns {@code true} if and only if the underlying class is a hidden class.
+ *
+ * @return {@code true} if and only if this class is a hidden class.
+ *
+ * @since 15
+ * @see MethodHandles.Lookup#defineHiddenClass
+ */
+ @HotSpotIntrinsicCandidate
+ public native boolean isHidden();
+
}
< prev index next >