< prev index next >

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

Print this page
rev 50075 : imported patch jep181-rev1
rev 50076 : [mq]: jep181-rev2

@@ -3846,6 +3846,160 @@
      * @since 1.8
      */
     public AnnotatedType[] getAnnotatedInterfaces() {
          return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
     }
+
+    private native Class<?> getNestHost0();
+
+    /**
+     * Returns the nest host of the object represented by this {@code Class}.
+     *
+     * <p>If there is any {@linkplain LinkageError linkage error} accessing the nest host,
+     * or the nest host is in any way invalid, then {@code this} is returned.
+     *
+     * <p>A <em>nest</em> is a set of classes and interfaces (nestmates) that
+     * form an access control context in which each nestmate has access to the
+     * private members of the other nestmates.
+     * The <em>nest host</em> is the class or interface designated to hold the list of
+     * classes and interfaces that make up the nest, and to which each of the
+     * other nestmates refer.
+     * All nestmates are implicitly defined in the same runtime package.
+     *
+     * <p>A class or interface that is not explicitly a member of a nest
+     * (such as a primitive or array class),
+     * is a member of the nest consisting only of itself, and is the
+     * nest host. Every class and interface is a member of exactly one nest.
+     *
+     * @apiNote The source language compiler is responsible for deciding which classes
+     * and interfaces are nestmates, by generating the appropriate attributes
+     * (JVMS 4.7.28 and 4.7.29) in the class file format (JVMS 4).
+     * For example, the {@code javac} compiler
+     * places a top-level class or interface into a nest with all of its direct,
+     * and indirect, {@linkplain #getDeclaredClasses() nested classes and interfaces}
+     * (JLS 8).
+     * The top-level {@linkplain #getEnclosingClass() enclosing class or interface}
+     * is designated as the nest host.
+     *
+     * @return the nest host of this class, or {@code this} if a valid nest host
+     * cannot be obtained
+     * @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
+     */
+    @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
+            return this;
+        }
+        // if null then nest membership validation failed, so we
+        // act as-if we have no nest-host
+        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
+     * object represented by this {@code Class}. Two classes 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 valid 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 declared in the
+     * {@linkplain #getNestHost() nest host} of this class, as being members
+     * of its nest. The nest host will always be the zeroth element.
+     *
+     * <p>Each listed nest member must be validated by checking its own
+     * declared nest host. Any exceptions that occur as part of this process
+     * will be thrown.
+     *
+     * <p>The list of nest members is permitted to contain duplicates, or to
+     * explicitly include the nest host, as specified in the Java Virtual Machine
+     * Specification. It is not required that an implementation of this method
+     * removes these duplicates.
+     *
+     * @implNote This implementation does not remove duplicate nest members if they
+     * are present.
+     *
+     * @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
+     * @jvms 4.7.29 NestMembers attribute
+     */
+    @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;
+    }
 }
< prev index next >