src/java.base/share/classes/java/lang/Class.java
changeset 50735 2f2af62dfac7
parent 50570 0d6f88cca118
child 52020 4c247dde38ed
--- a/src/java.base/share/classes/java/lang/Class.java	Fri Jun 22 17:49:21 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Class.java	Sat Jun 23 01:32:41 2018 -0400
@@ -82,9 +82,9 @@
 import sun.reflect.misc.ReflectUtil;
 
 /**
- * Instances of the class {@code Class} represent classes and
- * interfaces in a running Java application.  An enum is a kind of
- * class and an annotation is a kind of interface.  Every array also
+ * Instances of the class {@code Class} represent classes and interfaces
+ * in a running Java application. An enum type is a kind of class and an
+ * annotation type is a kind of interface. Every array also
  * belongs to a class that is reflected as a {@code Class} object
  * that is shared by all arrays with the same element type and number
  * of dimensions.  The primitive Java types ({@code boolean},
@@ -93,10 +93,34 @@
  * {@code double}), and the keyword {@code void} are also
  * represented as {@code Class} objects.
  *
- * <p> {@code Class} has no public constructor. Instead {@code Class}
- * objects are constructed automatically by the Java Virtual Machine as classes
- * are loaded and by calls to the {@code defineClass} method in the class
- * loader.
+ * <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
+ * classes and interfaces, in the same run-time package, that
+ * allow mutual access to their {@code private} members.
+ * The classes and interfaces are known as <em>nestmates</em>.
+ * One nestmate acts as the
+ * <em>nest host</em>, and enumerates the other nestmates which
+ * belong to the nest; each of them in turn records it as the nest host.
+ * The classes and interfaces which belong to a nest, including its host, are
+ * determined when
+ * {@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:
@@ -3848,4 +3872,161 @@
     public AnnotatedType[] getAnnotatedInterfaces() {
          return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
     }
+
+    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 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 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
+     *         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 the returned class and invocation of {@link
+     *         SecurityManager#checkPackageAccess s.checkPackageAccess()}
+     *         denies access to the package of the returned class
+     * @since 11
+     * @jvms 4.7.28 and 4.7.29 NestHost and NestMembers attributes
+     * @jvms 5.4.4 Access Control
+     */
+    @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) {
+            checkPackageAccess(sm,
+                               ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
+        }
+        return host;
+    }
+
+    /**
+     * Determines if the given {@code Class} is a nestmate of the
+     * class or interface represented by this {@code Class} object.
+     * Two classes or interfaces are nestmates
+     * if they have the same {@linkplain #getNestHost() nest host}.
+     *
+     * @param c the class to check
+     * @return {@code true} if this class and {@code c} are members of
+     * the same nest; and {@code false} otherwise.
+     *
+     * @since 11
+     */
+    public boolean isNestmateOf(Class<?> c) {
+        if (this == c) {
+            return true;
+        }
+        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 };
+        }
+        Class<?>[] members = getNestMembers0();
+        // Can't actually enable this due to bootstrapping issues
+        // assert(members.length != 1 || members[0] == this); // expected invariant from VM
+
+        if (members.length > 1) {
+            // If we return anything other than the current class we need
+            // a security check
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                checkPackageAccess(sm,
+                                   ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
+            }
+        }
+        return members;
+    }
 }