< 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 >