< prev index next >

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

Print this page

        

*** 3846,3851 **** --- 3846,4003 ---- * @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 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. + * + * <p>A class or interface that is not explicitly a member of a nest, + * 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 we cannot + * obtain a valid nest host + * @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 >