< prev index next > src/java.base/share/classes/java/lang/Class.java
Print this page
import java.io.ObjectStreamField;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.AccessFlag;
import java.lang.reflect.Array;
+ import java.lang.reflect.ClassFileFormatVersion;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
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 {
registerNatives();
}
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 {
registerNatives();
}
} while (component.isArray());
sb.append(component.getName());
} else {
// Class modifiers are a superset of interface modifiers
int modifiers = getModifiers() & Modifier.classModifiers();
+ // Modifier.toString() below mis-interprets SYNCHRONIZED, STRICT, and VOLATILE bits
+ modifiers &= ~(Modifier.SYNCHRONIZED | Modifier.STRICT | Modifier.VOLATILE);
if (modifiers != 0) {
sb.append(Modifier.toString(modifiers));
sb.append(' ');
}
addSealingInfo(modifiers, sb);
if (isAnnotation()) {
sb.append('@');
}
+ if (isValue()) {
+ sb.append("value ");
+ }
if (isInterface()) { // Note: all annotation interfaces are interfaces
sb.append("interface");
} else {
if (isEnum())
sb.append("enum");
} else {
return BootLoader.loadClass(module, name);
}
}
+ /**
+ * {@return {@code true} if this {@code Class} object represents an identity
+ * class or interface; otherwise {@code false}}
+ *
+ * If this {@code Class} object represents an array type, then this method
+ * returns {@code true}.
+ * If this {@code Class} object represents a primitive type, or {@code void},
+ * then this method returns {@code false}.
+ *
+ * @since Valhalla
+ */
+ @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS, reflective=true)
+ public native boolean isIdentity();
+
+ /**
+ * {@return {@code true} if this {@code Class} object represents a value
+ * class; otherwise {@code false}}
+ *
+ * If this {@code Class} object represents an array type, an interface,
+ * a primitive type, or {@code void}, then this method returns {@code false}.
+ *
+ * @since Valhalla
+ */
+ @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS, reflective=true)
+ public boolean isValue() {
+ if (!PreviewFeatures.isEnabled()) {
+ return false;
+ }
+ if (isPrimitive() || isArray() || isInterface())
+ return false;
+ return ((getModifiers() & Modifier.IDENTITY) == 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.
* 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> its {@code 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
* @jvms 4.1 The {@code ClassFile} Structure
*/
@IntrinsicCandidate
public native int getModifiers();
! /**
* {@return an unmodifiable set of the {@linkplain AccessFlag access
* flags} for this class, possibly empty}
*
* <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
* </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 {@code ClassFile} Structure
*/
@IntrinsicCandidate
public native int getModifiers();
! /**
* {@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> its {@code identity} modifier is always true
* </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
// Use getClassAccessFlagsRaw to expose SUPER status.
var location = (isMemberClass() || isLocalClass() ||
isAnonymousClass() || isArray()) ?
AccessFlag.Location.INNER_CLASS :
AccessFlag.Location.CLASS;
! return AccessFlag.maskToAccessFlags((location == AccessFlag.Location.CLASS) ?
! getClassAccessFlagsRaw() :
! getModifiers(),
! location);
}
! /**
* Gets the signers of this class.
*
* @return the signers of this class, or null if there are no signers. In
* particular, this method returns null if this {@code Class} object represents
* a primitive type or void.
* @since 1.1
*/
public Object[] getSigners() {
var signers = this.signers;
return signers == null ? null : signers.clone();
}
// Use getClassAccessFlagsRaw to expose SUPER status.
var location = (isMemberClass() || isLocalClass() ||
isAnonymousClass() || isArray()) ?
AccessFlag.Location.INNER_CLASS :
AccessFlag.Location.CLASS;
! int accessFlags = (location == AccessFlag.Location.CLASS) ?
! getClassAccessFlagsRaw() : getModifiers();
! if (isArray() && PreviewFeatures.isEnabled()) {
! accessFlags |= Modifier.IDENTITY;
+ }
+ var cffv = ClassFileFormatVersion.fromMajor(getClassFileVersion() & 0xffff);
+ if (cffv.compareTo(ClassFileFormatVersion.latest()) >= 0) {
+ // Ignore unspecified (0x0800) access flag for current version
+ accessFlags &= ~0x0800;
+ }
+ return AccessFlag.maskToAccessFlags(accessFlags, location, cffv);
}
! /**
* Gets the signers of this class.
*
* @return the signers of this class, or null if there are no signers. In
* particular, this method returns null if this {@code Class} object represents
* a primitive type or void.
* @since 1.1
*/
+
public Object[] getSigners() {
var signers = this.signers;
return signers == null ? null : signers.clone();
}
*
* @return an array representing the superinterfaces
* @since 1.8
*/
public AnnotatedType[] getAnnotatedInterfaces() {
! return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
}
private native Class<?> getNestHost0();
/**
*
* @return an array representing the superinterfaces
* @since 1.8
*/
public AnnotatedType[] getAnnotatedInterfaces() {
! return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
}
private native Class<?> getNestHost0();
/**
*
* If the class is an array type then the class file version of its element
* type is returned. If the class is a primitive type then the latest class
* file major version is returned and zero is returned for the minor version.
*/
! private int getClassFileVersion() {
Class<?> c = isArray() ? elementType() : this;
return c.getClassFileVersion0();
}
private native int getClassFileVersion0();
*
* If the class is an array type then the class file version of its element
* type is returned. If the class is a primitive type then the latest class
* file major version is returned and zero is returned for the minor version.
*/
! /* package-private */
+ int getClassFileVersion() {
Class<?> c = isArray() ? elementType() : this;
return c.getClassFileVersion0();
}
private native int getClassFileVersion0();
< prev index next >