< prev index next > src/java.base/share/classes/java/lang/Class.java
Print this page
import java.lang.reflect.Modifier;
import java.lang.reflect.RecordComponent;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.constant.Constable;
+ import java.lang.classfile.ClassFile;
import java.net.URL;
import java.security.AllPermission;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import jdk.internal.constant.ConstantUtils;
+ import jdk.internal.javac.PreviewFeature;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
+ import jdk.internal.misc.PreviewFeatures;
import jdk.internal.misc.Unsafe;
import jdk.internal.module.Resources;
+ import jdk.internal.reflect.AccessFlagSet;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.CallerSensitiveAdapter;
import jdk.internal.reflect.ConstantPool;
+ import jdk.internal.reflect.PreviewAccessFlags;
import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory;
import jdk.internal.util.ModifiedUtf;
import jdk.internal.vm.annotation.AOTRuntimeSetup;
import jdk.internal.vm.annotation.AOTSafeClassInitializer;
GenericDeclaration,
Type,
AnnotatedElement,
TypeDescriptor.OfField<Class<?>>,
Constable {
- private static final int ANNOTATION = 0x00002000;
- private static final int ENUM = 0x00004000;
- private static final int SYNTHETIC = 0x00001000;
private static native void registerNatives();
static {
runtimeSetup();
}
if (isInterface()) { // Note: all annotation interfaces are interfaces
sb.append("interface");
} else {
if (isEnum())
sb.append("enum");
! else if (isRecord())
! sb.append("record");
! else
! sb.append("class");
}
sb.append(' ');
sb.append(getName());
}
if (isInterface()) { // Note: all annotation interfaces are interfaces
sb.append("interface");
} else {
if (isEnum())
sb.append("enum");
! else {
! if (isValue()) {
! sb.append("value ");
! }
+ if (isRecord())
+ sb.append("record");
+ else
+ sb.append("class");
+ }
}
sb.append(' ');
sb.append(getName());
}
} else {
return BootLoader.loadClass(module, name);
}
}
+ /**
+ * {@return {@code true} if this {@code Class} object represents a value class,
+ * otherwise {@code false}}
+ *
+ * <p>A value class is declared with the {@code value} modifier. If this
+ * {@code Class} object represents an interface, array type, primitive type,
+ * or {@code void}, the result is {@code false}.
+ *
+ * @jls value-objects-8.1.1.5 {@code value} Classes
+ * @see AccessFlag#IDENTITY
+ * @since Valhalla
+ */
+ @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS, reflective=true)
+ public boolean isValue() {
+ if (!PreviewFeatures.isEnabled()) {
+ return false;
+ } else {
+ int mask = ClassFile.ACC_IDENTITY | ClassFile.ACC_INTERFACE;
+ return !primitive && (getModifiers() & mask) == 0;
+ }
+ }
+
/**
* {@return the {@code Class} object associated with the
* {@linkplain #isPrimitive() primitive type} of the given name}
* If the argument is not the name of a primitive type, {@code
* null} is returned.
* @return {@code true} if this {@code Class} object represents an annotation
* interface; {@code false} otherwise
* @since 1.5
*/
public boolean isAnnotation() {
! return (getModifiers() & ANNOTATION) != 0;
}
/**
*{@return {@code true} if and only if this class has the synthetic modifier
* bit set}
* @return {@code true} if this {@code Class} object represents an annotation
* interface; {@code false} otherwise
* @since 1.5
*/
public boolean isAnnotation() {
! return (getModifiers() & ClassFile.ACC_ANNOTATION) != 0;
}
/**
*{@return {@code true} if and only if this class has the synthetic modifier
* bit set}
* href="{@docRoot}/java.base/java/lang/reflect/package-summary.html#LanguageJvmModel">Java
* programming language and JVM modeling in core reflection</a>
* @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.
* href="{@docRoot}/java.base/java/lang/reflect/package-summary.html#LanguageJvmModel">Java
* programming language and JVM modeling in core reflection</a>
* @since 1.5
*/
public boolean isSynthetic() {
! return (getModifiers() & ClassFile.ACC_SYNTHETIC) != 0;
}
/**
* Returns the name of the entity (class, interface, array class,
* primitive type, or void) represented by this {@code Class} object.
private transient Object classData; // Set by VM
private transient Object[] signers; // Read by VM, mutable
private final transient char modifiers; // Set by the VM
private final transient char classFileAccessFlags; // Set by the VM
! private final transient boolean primitive; // Set by the VM if the Class is a primitive type.
// package-private
Object getClassData() {
return classData;
}
private transient Object classData; // Set by VM
private transient Object[] signers; // Read by VM, mutable
private final transient char modifiers; // Set by the VM
private final transient char classFileAccessFlags; // Set by the VM
! private final transient boolean primitive; // Set by the VM if the Class is a primitive type
// package-private
Object getClassData() {
return classData;
}
* modifiers are the same as those of its component type
* <li> its {@code abstract} and {@code final} modifiers are always
* {@code true}
* <li> its interface modifier is always {@code false}, even when
* the component type is an interface
+ * <li> when preview features are enabled, its {@linkplain
+ * AccessFlag#IDENTITY identity} modifier is always true
* </ul>
* If this {@code Class} object represents a primitive type or
* void, its {@code public}, {@code abstract}, and {@code final}
* modifiers are always {@code true}.
* For {@code Class} objects representing void, primitive types, and
public int getModifiers() { return modifiers; }
/**
* {@return an unmodifiable set of the {@linkplain AccessFlag access
* flags} for this class, possibly empty}
+ * The {@code AccessFlags} may depend on the class file format version of the class.
*
* <p> If the underlying class is an array class:
* <ul>
* <li> its {@code PUBLIC}, {@code PRIVATE} and {@code PROTECTED}
* access flags are the same as those of its component type
* <li> its {@code ABSTRACT} and {@code FINAL} flags are present
* <li> its {@code INTERFACE} flag is absent, even when the
* component type is an interface
+ * <li> when preview features are enabled, its {@code IDENTITY} flag
+ * is present
* </ul>
* If this {@code Class} object represents a primitive type or
* void, the flags are {@code PUBLIC}, {@code ABSTRACT}, and
* {@code FINAL}.
* For {@code Class} objects representing void, primitive types, and
* @jvms 4.1 The ClassFile Structure
* @jvms 4.7.6 The InnerClasses Attribute
* @since 20
*/
public Set<AccessFlag> accessFlags() {
! // Location.CLASS allows SUPER and AccessFlag.MODULE which
! // INNER_CLASS forbids. INNER_CLASS allows PRIVATE, PROTECTED,
! // and STATIC, which are not allowed on Location.CLASS.
! // Use getClassFileAccessFlags to expose SUPER status.
! // Arrays need to use PRIVATE/PROTECTED from its component modifiers.
! var location = (isMemberClass() || isLocalClass() ||
! isAnonymousClass() || isArray()) ?
! AccessFlag.Location.INNER_CLASS :
! AccessFlag.Location.CLASS;
! return getReflectionFactory().parseAccessFlags((location == AccessFlag.Location.CLASS) ?
! getClassFileAccessFlags() : getModifiers(), location, this);
}
/**
* Gets the signers of this class.
*
* @jvms 4.1 The ClassFile Structure
* @jvms 4.7.6 The InnerClasses Attribute
* @since 20
*/
public Set<AccessFlag> accessFlags() {
! if (!PreviewFeatures.isEnabled()) {
! // INNER_CLASS_FLAGS exclusively defines PRIVATE, PROTECTED, and STATIC.
! // CLASS_FLAGS exclusively defines SUPER and MODULE.
! // Nested classes and interfaces need to report PRIVATE/PROTECTED/STATIC.
! // Arrays need to report PRIVATE/PROTECTED.
! // Top-level classes need to report SUPER, using getClassFileAccessFlags.
! // Module descriptors do not have Class objects so nothing reports MODULE.
! return (isArray() || getEnclosingClass() != null)
! ? AccessFlagSet.ofValidated(AccessFlagSet.INNER_CLASS_FLAGS, getModifiers())
! : AccessFlagSet.ofValidated(AccessFlagSet.CLASS_FLAGS, getClassFileAccessFlags());
! }
+ // CLASS_FLAGS exclusively defines MODULE, but module descriptors are
+ // never represented with Class objects, so INNER_CLASS_FLAGS works
+ return AccessFlagSet.ofValidated(PreviewAccessFlags.INNER_CLASS_PREVIEW_FLAGS, getModifiers());
}
/**
* Gets the signers of this class.
*
*/
public boolean isEnum() {
// An enum must both directly extend java.lang.Enum and have
// the ENUM bit set; classes for specialized enum constants
// don't do the former.
! return (this.getModifiers() & ENUM) != 0 &&
this.getSuperclass() == java.lang.Enum.class;
}
/**
* Returns {@code true} if and only if this class is a record class.
*/
public boolean isEnum() {
// An enum must both directly extend java.lang.Enum and have
// the ENUM bit set; classes for specialized enum constants
// don't do the former.
! return (this.getModifiers() & ClassFile.ACC_ENUM) != 0 &&
this.getSuperclass() == java.lang.Enum.class;
}
/**
* Returns {@code true} if and only if this class is a record class.
< prev index next >