< prev index next >

src/java.base/share/classes/java/lang/reflect/AccessFlag.java

Print this page
@@ -23,10 +23,12 @@
   * questions.
   */
  
  package java.lang.reflect;
  
+ import jdk.internal.javac.PreviewFeature;
+ 
  import java.lang.classfile.ClassModel;
  import java.lang.classfile.FieldModel;
  import java.lang.classfile.MethodModel;
  import java.lang.classfile.attribute.InnerClassInfo;
  import java.lang.classfile.attribute.MethodParameterInfo;

@@ -160,12 +162,29 @@
       * 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}).
+      * If preview feature is enabled,
+      * the {@code 0x0020} access flag bit is {@linkplain #IDENTITY IDENTITY access flag}.
+      */
+     SUPER(0x0000_0020, false,
+           Location.EMPTY_SET,
+           List.of(Map.entry(latest(), Location.SET_CLASS))),
+ 
+     /**
+      * The access flag {@code ACC_IDENTITY}, corresponding to the
+      * 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
+      *
+      * @since Valhalla
       */
-     SUPER(0x0000_0020, false, Location.SET_CLASS, List.of()),
+     @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS, reflective=true)
+     IDENTITY(Modifier.IDENTITY, false,
+              Location.SET_CLASS_INNER_CLASS,
+              List.of(Map.entry(latest(), Location.EMPTY_SET))),
  
      /**
       * The module flag {@code ACC_OPEN} with a mask value of {@code
       * 0x0020}.
       * @see java.lang.module.ModuleDescriptor#isOpen

@@ -262,10 +281,22 @@
       */
      STRICT(Modifier.STRICT, true, Location.EMPTY_SET,
             List.of(Map.entry(RELEASE_16, Location.SET_METHOD),
                     Map.entry(RELEASE_1, Location.EMPTY_SET))),
  
+     /**
+      * The access flag {@code ACC_STRICT_INIT}, with a mask value of
+      * <code>{@value "0x%04x" java.lang.classfile.ClassFile#ACC_STRICT_INIT}</code>.
+      *
+      * @jvms 4.5 Fields
+      * @since Valhalla
+      */
+     @PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS, reflective=true)
+     STRICT_INIT(ACC_STRICT_INIT, false,
+                 Location.SET_FIELD,
+                 List.of(Map.entry(latest(), Location.EMPTY_SET))),
+ 
      /**
       * The access flag {@code ACC_SYNTHETIC} with a mask value of
       * <code>{@value "0x%04x" Modifier#SYNTHETIC}</code>.
       * @see Class#isSynthetic()
       * @see Executable#isSynthetic()

@@ -351,11 +382,11 @@
       * <p>
       * This method returns an empty set if this flag is not defined in
       * the current class file format version.
       */
      public Set<Location> locations() {
-         return locations;
+         return locations(latest());
      }
  
      /**
       * {@return locations this flag can be applied to in the given class file
       * format version}

@@ -379,18 +410,11 @@
       * @throws IllegalArgumentException if the mask contains bit
       * positions not defined for the location in the current class file format
       * @throws NullPointerException if {@code location} is {@code null}
       */
      public static Set<AccessFlag> maskToAccessFlags(int mask, Location location) {
-         var definition = findDefinition(location);  // null checks location
-         int unmatchedMask = mask & (~location.flagsMask());
-         if (unmatchedMask != 0) {
-             throw new IllegalArgumentException("Unmatched bit position 0x" +
-                     Integer.toHexString(unmatchedMask) +
-                     " for location " + location);
-         }
-         return new AccessFlagSet(definition, mask);
+         return maskToAccessFlags(mask, location, latest());
      }
  
      /**
       * {@return an unmodifiable set of access flags for the given mask value
       * appropriate for the location in the given class file format version}

@@ -402,11 +426,11 @@
       * positions not defined for the location in the given class file format
       * @throws NullPointerException if {@code location} or {@code cffv} is {@code null}
       * @since 25
       */
      public static Set<AccessFlag> maskToAccessFlags(int mask, Location location, ClassFileFormatVersion cffv) {
-         var definition = findDefinition(location);  // null checks location
+         var definition = findDefinition(location, cffv);  // null checks location
          int unmatchedMask = mask & (~location.flagsMask(cffv));  // null checks cffv
          if (unmatchedMask != 0) {
              throw new IllegalArgumentException("Unmatched bit position 0x" +
                      Integer.toHexString(unmatchedMask) +
                      " for location " + location +

@@ -431,11 +455,11 @@
           * @see ClassModel#flags()
           * @see Modifier#classModifiers()
           * @see Modifier#interfaceModifiers()
           * @jvms 4.1 The {@code ClassFile} Structure
           */
-         CLASS(ACC_PUBLIC | ACC_FINAL | ACC_SUPER |
+         CLASS(ACC_PUBLIC | ACC_FINAL | ACC_IDENTITY |
                ACC_INTERFACE | ACC_ABSTRACT |
                ACC_SYNTHETIC | ACC_ANNOTATION |
                ACC_ENUM | ACC_MODULE,
                List.of(Map.entry(RELEASE_8, // no module
                                  ACC_PUBLIC | ACC_FINAL | ACC_SUPER |

@@ -453,12 +477,16 @@
           * @see Modifier#fieldModifiers()
           * @jvms 4.5 Fields
           */
          FIELD(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
                ACC_STATIC | ACC_FINAL | ACC_VOLATILE |
-               ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM,
-               List.of(Map.entry(RELEASE_4, // no synthetic, enum
+               ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM | ACC_STRICT_INIT,
+               List.of(Map.entry(latest(), // no strict_init
+                                 ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
+                                 ACC_STATIC | ACC_FINAL | ACC_VOLATILE |
+                                 ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM),
+                       Map.entry(RELEASE_4, // no synthetic, enum
                                  ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
                                  ACC_STATIC | ACC_FINAL | ACC_VOLATILE |
                                  ACC_TRANSIENT))),
  
          /**

@@ -495,17 +523,21 @@
           * @see InnerClassInfo#flags()
           * @see Modifier#classModifiers()
           * @see Modifier#interfaceModifiers()
           * @jvms 4.7.6 The {@code InnerClasses} Attribute
           */
-         INNER_CLASS(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
+         INNER_CLASS(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_IDENTITY |
                      ACC_STATIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT |
                      ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM,
-                     List.of(Map.entry(RELEASE_4, // no synthetic, annotation, enum
-                             ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
-                             ACC_STATIC | ACC_FINAL | ACC_INTERFACE |
-                             ACC_ABSTRACT),
+                     List.of(Map.entry(latest(), // no identity
+                                       ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
+                                       ACC_STATIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT |
+                                       ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM),
+                             Map.entry(RELEASE_4, // no synthetic, annotation, enum
+                                       ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED |
+                                       ACC_STATIC | ACC_FINAL | ACC_INTERFACE |
+                                       ACC_ABSTRACT),
                              Map.entry(RELEASE_0, 0))), // did not exist
  
          /**
           * Method parameter location.
           *

@@ -618,11 +650,11 @@
  
          // Ensures the historical versions are from newest to oldest and do not include the latest
          // These 2 utilities reside in Location because Location must be initialized before AccessFlag
          private static <T> List<Map.Entry<ClassFileFormatVersion, T>> ensureHistoryOrdered(
                  List<Map.Entry<ClassFileFormatVersion, T>> history) {
-             ClassFileFormatVersion lastVersion = ClassFileFormatVersion.latest();
+             ClassFileFormatVersion lastVersion = CURRENT_PREVIEW_FEATURES;
              for (var e : history) {
                  var historyVersion = e.getKey();
                  if (lastVersion.compareTo(historyVersion) <= 0) {
                      throw new IllegalArgumentException("Versions out of order");
                  }

@@ -652,11 +684,11 @@
           * the current class file format version.
           *
           * @since 25
           */
          public int flagsMask() {
-             return flagsMask;
+             return flagsMask(latest());
          }
  
          /**
           * {@return the union of masks of all access flags defined for
           * this location in the given class file format version}

@@ -680,11 +712,11 @@
           * in the current class file format version.
           *
           * @since 25
           */
          public Set<AccessFlag> flags() {
-             return new AccessFlagSet(findDefinition(this), flagsMask());
+             return flags(latest());
          }
  
          /**
           * {@return the set of access flags defined for this location in the
           * given class file format version}  The set is immutable.

@@ -696,11 +728,11 @@
           * @throws NullPointerException if {@code cffv} is {@code null}
           * @since 25
           */
          public Set<AccessFlag> flags(ClassFileFormatVersion cffv) {
              // implicit null check cffv
-             return new AccessFlagSet(findDefinition(this), flagsMask(cffv));
+             return new AccessFlagSet(findDefinition(this, cffv), flagsMask(cffv));
          }
      }
  
      private static AccessFlag[] createDefinition(AccessFlag... known) {
          var ret = new AccessFlag[Character.SIZE];

@@ -711,30 +743,32 @@
              ret[pos] = flag;
          }
          return ret;
      }
  
-     // Will take extra args in the future for valhalla switch
-     private static AccessFlag[] findDefinition(Location location) {
+     private static AccessFlag[] findDefinition(Location location, ClassFileFormatVersion cffv) {
          return switch (location) {
-             case CLASS -> CLASS_FLAGS;
-             case FIELD -> FIELD_FLAGS;
+             case CLASS -> cffv == CURRENT_PREVIEW_FEATURES ? CLASS_PREVIEW_FLAGS : CLASS_FLAGS;
+             case FIELD -> cffv == CURRENT_PREVIEW_FEATURES ? FIELD_PREVIEW_FLAGS : FIELD_FLAGS;
              case METHOD -> METHOD_FLAGS;
-             case INNER_CLASS -> INNER_CLASS_FLAGS;
+             case INNER_CLASS -> cffv == CURRENT_PREVIEW_FEATURES ? INNER_CLASS_PREVIEW_FLAGS : INNER_CLASS_FLAGS;
              case METHOD_PARAMETER -> METHOD_PARAMETER_FLAGS;
              case MODULE -> MODULE_FLAGS;
              case MODULE_REQUIRES -> MODULE_REQUIRES_FLAGS;
              case MODULE_EXPORTS -> MODULE_EXPORTS_FLAGS;
              case MODULE_OPENS -> MODULE_OPENS_FLAGS;
          };
      }
  
      private static final @Stable AccessFlag[] // Can use stable array and lazy init in the future
-             CLASS_FLAGS = createDefinition(PUBLIC, FINAL, SUPER, INTERFACE, ABSTRACT, SYNTHETIC, ANNOTATION, ENUM, MODULE),
-             FIELD_FLAGS = createDefinition(PUBLIC, PRIVATE, PROTECTED, STATIC, FINAL, VOLATILE, TRANSIENT, SYNTHETIC, ENUM),
+             CLASS_FLAGS         = createDefinition(PUBLIC, FINAL, SUPER, INTERFACE, ABSTRACT, SYNTHETIC, ANNOTATION, ENUM, MODULE),
+             CLASS_PREVIEW_FLAGS = createDefinition(PUBLIC, FINAL, IDENTITY, INTERFACE, ABSTRACT, SYNTHETIC, ANNOTATION, ENUM, MODULE), // identity
+             FIELD_FLAGS         = createDefinition(PUBLIC, PRIVATE, PROTECTED, STATIC, FINAL, VOLATILE, TRANSIENT, SYNTHETIC, ENUM),
+             FIELD_PREVIEW_FLAGS = createDefinition(PUBLIC, PRIVATE, PROTECTED, STATIC, FINAL, VOLATILE, TRANSIENT, SYNTHETIC, ENUM, STRICT_INIT), // strict
              METHOD_FLAGS = createDefinition(PUBLIC, PRIVATE, PROTECTED, STATIC, FINAL, SYNCHRONIZED, BRIDGE, VARARGS, NATIVE, ABSTRACT, STRICT, SYNTHETIC),
-             INNER_CLASS_FLAGS = createDefinition(PUBLIC, PRIVATE, PROTECTED, STATIC, FINAL, INTERFACE, ABSTRACT, SYNTHETIC, ANNOTATION, ENUM),
+             INNER_CLASS_FLAGS         = createDefinition(PUBLIC, PRIVATE, PROTECTED, STATIC, FINAL, INTERFACE, ABSTRACT, SYNTHETIC, ANNOTATION, ENUM),
+             INNER_CLASS_PREVIEW_FLAGS = createDefinition(PUBLIC, PRIVATE, PROTECTED, IDENTITY, STATIC, FINAL, INTERFACE, ABSTRACT, SYNTHETIC, ANNOTATION, ENUM),  // identity
              METHOD_PARAMETER_FLAGS = createDefinition(FINAL, SYNTHETIC, MANDATED),
              MODULE_FLAGS = createDefinition(OPEN, SYNTHETIC, MANDATED),
              MODULE_REQUIRES_FLAGS = createDefinition(TRANSITIVE, STATIC_PHASE, SYNTHETIC, MANDATED),
              MODULE_EXPORTS_FLAGS = createDefinition(SYNTHETIC, MANDATED),
              MODULE_OPENS_FLAGS = createDefinition(SYNTHETIC, MANDATED);
< prev index next >