< prev index next > src/java.base/share/classes/java/lang/reflect/AccessFlag.java
Print this page
* questions.
*/
package java.lang.reflect;
+ import jdk.internal.misc.ValhallaFeatures;
+
import java.util.Collections;
import java.util.Objects;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
* 0x0020}.
*
* @apiNote
* In Java SE 8 and above, the JVM treats the {@code ACC_SUPER}
* flag as set in every class file (JVMS {@jvms 4.1}).
+ * For class file versions up to Valhalla or if Valhalla is not enabled,
+ * {@code 0x0020} access flag bit is {@linkplain #SUPER SUPER access flag}; otherwise,
+ * the {@code 0x0020} access flag bit is {@linkplain #IDENTITY IDENTITY access flag}.
+ */
+ SUPER(0x0000_0020, false,
+ ValhallaFeatures.isEnabled() ? Location.EMPTY_SET : Location.SET_CLASS,
+ new Function<ClassFileFormatVersion, Set<Location>>() {
+ @Override
+ public Set<Location> apply(ClassFileFormatVersion cffv) {
+ return (cffv.compareTo(ClassFileFormatVersion.RELEASE_21) >= 0 &&
+ ValhallaFeatures.isEnabled()) ? Location.EMPTY_SET : Location.SET_CLASS;}
+ }),
+
+ /**
+ * The access flag {@code ACC_IDENTITY}, corresponding to the
+ * source modifier {@link Modifier#IDENTITY identity}, with a mask
+ * value of <code>{@value "0x%04x" Modifier#IDENTITY}</code>.
+ * @jvms 4.1 -B. Class access and property modifiers
*/
- SUPER(0x0000_0020, false, Location.SET_CLASS, null),
+ IDENTITY(Modifier.IDENTITY, true,
+ ValhallaFeatures.isEnabled() ? Location.SET_CLASS_INNER_CLASS : Location.EMPTY_SET,
+ new Function<ClassFileFormatVersion, Set<Location>>() {
+ @Override
+ public Set<Location> apply(ClassFileFormatVersion cffv) {
+ return (cffv.compareTo(ClassFileFormatVersion.RELEASE_21) >= 0 &&
+ ValhallaFeatures.isEnabled()) ? Location.SET_CLASS_INNER_CLASS : Location.EMPTY_SET;}
+ }),
/**
* The module flag {@code ACC_OPEN} with a mask value of {@code
* 0x0020}.
* @see java.lang.module.ModuleDescriptor#isOpen
*/
- OPEN(0x0000_0020, false, Location.SET_MODULE,
- new Function<ClassFileFormatVersion, Set<Location>>() {
- @Override
- public Set<Location> apply(ClassFileFormatVersion cffv) {
- return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
- Location.SET_MODULE:
- Location.EMPTY_SET;}
- }),
+ OPEN(0x0000_0020, false, Location.SET_MODULE,
+ new Function<ClassFileFormatVersion, Set<Location>>() {
+ @Override
+ public Set<Location> apply(ClassFileFormatVersion cffv) {
+ return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
+ Location.SET_MODULE:
+ Location.EMPTY_SET;}
+ }),
/**
* The module requires flag {@code ACC_TRANSITIVE} with a mask
* value of {@code 0x0020}.
* @see java.lang.module.ModuleDescriptor.Requires.Modifier#TRANSITIVE
return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
Location.SET_MODULE_REQUIRES:
Location.EMPTY_SET;}
}),
- /**
+ /**
+ * The access flag {@code ACC_VALUE}, corresponding to the
+ * source modifier {@link Modifier#VALUE value}, with a mask
+ * value of <code>{@value "0x%04x" Modifier#VALUE}</code>.
+ * @jvms 4.1 -B. Class access and property modifiers
+ */
+ VALUE(Modifier.VALUE, true, Set.of(Location.CLASS, Location.INNER_CLASS), null),
+
+ /**
* The access flag {@code ACC_VOLATILE}, corresponding to the
* source modifier {@link Modifier#VOLATILE volatile}, with a mask
* value of <code>{@value "0x%04x" Modifier#VOLATILE}</code>.
*/
VOLATILE(Modifier.VOLATILE, true, Location.SET_FIELD, null),
* appropriate for the location in question}
*
* @param mask bit mask of access flags
* @param location context to interpret mask value
* @throws IllegalArgumentException if the mask contains bit
- * positions not support for the location in question
+ * positions not supported for the location in question
*/
public static Set<AccessFlag> maskToAccessFlags(int mask, Location location) {
Set<AccessFlag> result = java.util.EnumSet.noneOf(AccessFlag.class);
for (var accessFlag : LocationToFlags.locationToFlags.get(location)) {
int accessMask = accessFlag.mask();
- if ((mask & accessMask) != 0) {
+ if ((mask & accessMask) != 0) {
result.add(accessFlag);
mask = mask & ~accessMask;
+ if (mask == 0) {
+ break; // no more mask bits
+ }
}
}
if (mask != 0) {
throw new IllegalArgumentException("Unmatched bit position 0x" +
Integer.toHexString(mask) +
" for location " + location);
}
return Collections.unmodifiableSet(result);
}
+ /**
+ * {@return an unmodifiable set of access flags for the given mask value
+ * appropriate for the location in question}
+ *
+ * @param mask bit mask of access flags
+ * @param location context to interpret mask value
+ * @param cffv the class file format version
+ * @throws IllegalArgumentException if the mask contains bit
+ * positions not supported for the location in question
+ */
+ public static Set<AccessFlag> maskToAccessFlags(int mask, Location location,
+ ClassFileFormatVersion cffv) {
+ Set<AccessFlag> result = java.util.EnumSet.noneOf(AccessFlag.class);
+ for (var accessFlag : AccessFlag.values()) {
+ int accessMask = accessFlag.mask();
+ if ((mask & accessMask) != 0) {
+ var locations = accessFlag.locations(cffv);
+ if (locations.contains(location)) {
+ result.add(accessFlag);
+ mask = mask & ~accessMask;
+ if (mask == 0) {
+ break; // no more mask bits
+ }
+ }
+ }
+ }
+ if (mask != 0) {
+ throw new IllegalArgumentException("Unmatched bit position 0x" +
+ Integer.toHexString(mask) +
+ " for location " + location +
+ " for class file format version " + cffv);
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+
/**
* A location within a class file where flags can be applied.
*
* Note that since these locations represent class file structures
* rather than language structures many language structures, such
}
private static class LocationToFlags {
private static Map<Location, Set<AccessFlag>> locationToFlags =
Map.ofEntries(entry(Location.CLASS,
- Set.of(PUBLIC, FINAL, SUPER,
+ Set.of(PUBLIC, FINAL, IDENTITY, VALUE,
INTERFACE, ABSTRACT,
SYNTHETIC, ANNOTATION,
ENUM, AccessFlag.MODULE)),
entry(Location.FIELD,
Set.of(PUBLIC, PRIVATE, PROTECTED,
Set.of(PUBLIC, PRIVATE, PROTECTED,
STATIC, FINAL, SYNCHRONIZED,
BRIDGE, VARARGS, NATIVE,
ABSTRACT, STRICT, SYNTHETIC)),
entry(Location.INNER_CLASS,
- Set.of(PUBLIC, PRIVATE, PROTECTED,
+ Set.of(PUBLIC, PRIVATE, PROTECTED, IDENTITY, VALUE,
STATIC, FINAL, INTERFACE, ABSTRACT,
SYNTHETIC, ANNOTATION, ENUM)),
entry(Location.METHOD_PARAMETER,
Set.of(FINAL, SYNTHETIC, MANDATED)),
entry(Location.MODULE,
< prev index next >