< prev index next >

src/java.base/share/classes/java/lang/invoke/MemberName.java

Print this page
@@ -23,10 +23,11 @@
   * questions.
   */
  
  package java.lang.invoke;
  
+ import jdk.internal.value.PrimitiveClass;
  import sun.invoke.util.BytecodeDescriptor;
  import sun.invoke.util.VerifyAccess;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Field;

@@ -99,11 +100,12 @@
      }
  
      /** Return the simple name of this member.
       *  For a type, it is the same as {@link Class#getSimpleName}.
       *  For a method or field, it is the simple name of the member.
-      *  For a constructor, it is always {@code "<init>"}.
+      *  For an identity object constructor, it is {@code "<init>"}.
+      *  For a value class static factory method, it is {@code "<vnew>"}.
       */
      public String getName() {
          if (name == null) {
              expandFromVM();
              if (name == null) {

@@ -189,14 +191,15 @@
       *  For non-static methods or constructors, this is the type with a leading parameter,
       *  a reference to declaring class.  For static methods, it is the same as the declared type.
       */
      public MethodType getInvocationType() {
          MethodType itype = getMethodOrFieldType();
-         if (isConstructor() && getReferenceKind() == REF_newInvokeSpecial)
-             return itype.changeReturnType(clazz);
+         Class<?> c = PrimitiveClass.isPrimitiveClass(clazz) ? PrimitiveClass.asValueType(clazz) : clazz;
+         if (isObjectConstructor() && getReferenceKind() == REF_newInvokeSpecial)
+             return itype.changeReturnType(c);
          if (!isStatic())
-             return itype.insertParameterTypes(0, clazz);
+             return itype.insertParameterTypes(0, c);
          return itype;
      }
  
      /** Utility method producing the parameter types of the method type. */
      public Class<?>[] getParameterTypes() {

@@ -281,11 +284,11 @@
          byte refKind = getReferenceKind();
          if (refKind == REF_NONE)  return isType();
          if (isField()) {
              assert(staticIsConsistent());
              assert(MethodHandleNatives.refKindIsField(refKind));
-         } else if (isConstructor()) {
+         } else if (isObjectConstructor()) {
              assert(refKind == REF_newInvokeSpecial || refKind == REF_invokeSpecial);
          } else if (isMethod()) {
              assert(staticIsConsistent());
              assert(MethodHandleNatives.refKindIsMethod(refKind));
              if (clazz.isInterface())

@@ -427,10 +430,12 @@
      public boolean isProtected() {
          return Modifier.isProtected(flags);
      }
      /** Utility method to query the modifier flags of this member. */
      public boolean isFinal() {
+         // all fields declared in a value type are effectively final
+         assert(!clazz.isValue() || !isField() || Modifier.isFinal(flags));
          return Modifier.isFinal(flags);
      }
      /** Utility method to query whether this member or its defining class is final. */
      public boolean canBeStaticallyBound() {
          return Modifier.isFinal(flags | clazz.getModifiers());

@@ -448,15 +453,16 @@
          return Modifier.isNative(flags);
      }
      // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
  
      // unofficial modifier flags, used by HotSpot:
-     static final int BRIDGE    = 0x00000040;
-     static final int VARARGS   = 0x00000080;
-     static final int SYNTHETIC = 0x00001000;
-     static final int ANNOTATION= 0x00002000;
-     static final int ENUM      = 0x00004000;
+     static final int BRIDGE      = 0x00000040;
+     static final int VARARGS     = 0x00000080;
+     static final int SYNTHETIC   = 0x00001000;
+     static final int ANNOTATION  = 0x00002000;
+     static final int ENUM        = 0x00004000;
+ 
      /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
      public boolean isBridge() {
          return testAllFlags(IS_METHOD | BRIDGE);
      }
      /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */

@@ -466,27 +472,40 @@
      /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
      public boolean isSynthetic() {
          return testAllFlags(SYNTHETIC);
      }
  
-     static final String CONSTRUCTOR_NAME = "<init>";  // the ever-popular
+     /** Query whether this member is a flattened field */
+     public boolean isFlattened() { return (flags & MN_FLATTENED) == MN_FLATTENED; }
+ 
+     /** Query whether this member is a field of a primitive class. */
+     public boolean isInlineableField()  {
+         if (isField()) {
+             Class<?> type = getFieldType();
+             return PrimitiveClass.isPrimitiveValueType(type) || (type.isValue() && !PrimitiveClass.isPrimitiveClass(type));
+         }
+         return false;
+     }
+ 
+     static final String CONSTRUCTOR_NAME = "<init>";
+     static final String VALUE_FACTORY_NAME = "<vnew>";  // the ever-popular
  
      // modifiers exported by the JVM:
      static final int RECOGNIZED_MODIFIERS = 0xFFFF;
  
      // private flags, not part of RECOGNIZED_MODIFIERS:
      static final int
-             IS_METHOD        = MN_IS_METHOD,        // method (not constructor)
-             IS_CONSTRUCTOR   = MN_IS_CONSTRUCTOR,   // constructor
-             IS_FIELD         = MN_IS_FIELD,         // field
-             IS_TYPE          = MN_IS_TYPE,          // nested type
-             CALLER_SENSITIVE = MN_CALLER_SENSITIVE, // @CallerSensitive annotation detected
-             TRUSTED_FINAL    = MN_TRUSTED_FINAL;    // trusted final field
+             IS_METHOD             = MN_IS_METHOD,              // method (not object constructor)
+             IS_OBJECT_CONSTRUCTOR = MN_IS_OBJECT_CONSTRUCTOR,  // object constructor
+             IS_FIELD              = MN_IS_FIELD,               // field
+             IS_TYPE               = MN_IS_TYPE,                // nested type
+             CALLER_SENSITIVE      = MN_CALLER_SENSITIVE,       // @CallerSensitive annotation detected
+             TRUSTED_FINAL         = MN_TRUSTED_FINAL;    // trusted final field
  
      static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
-     static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
-     static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
+     static final int ALL_KINDS = IS_METHOD | IS_OBJECT_CONSTRUCTOR | IS_FIELD | IS_TYPE;
+     static final int IS_INVOCABLE = IS_METHOD | IS_OBJECT_CONSTRUCTOR;
      static final int IS_FIELD_OR_METHOD = IS_METHOD | IS_FIELD;
      static final int SEARCH_ALL_SUPERS = MN_SEARCH_SUPERCLASSES | MN_SEARCH_INTERFACES;
  
      /** Utility method to query whether this member is a method or constructor. */
      public boolean isInvocable() {

@@ -499,13 +518,18 @@
      /** Query whether this member is a method. */
      public boolean isMethod() {
          return testAllFlags(IS_METHOD);
      }
      /** Query whether this member is a constructor. */
-     public boolean isConstructor() {
-         return testAllFlags(IS_CONSTRUCTOR);
+     public boolean isObjectConstructor() {
+         return testAllFlags(IS_OBJECT_CONSTRUCTOR);
+     }
+     /** Query whether this member is an object constructor or static <init> factory */
+     public boolean isStaticValueFactoryMethod() {
+         return VALUE_FACTORY_NAME.equals(name) && isMethod();
      }
+ 
      /** Query whether this member is a field. */
      public boolean isField() {
          return testAllFlags(IS_FIELD);
      }
      /** Query whether this member is a type. */

@@ -631,11 +655,11 @@
          throw new IllegalArgumentException(this.toString());
      }
      /** If this MN is not REF_newInvokeSpecial, return a clone with that ref. kind.
       *  In that case it must already be REF_invokeSpecial.
       */
-     public MemberName asConstructor() {
+     public MemberName asObjectConstructor() {
          switch (getReferenceKind()) {
          case REF_invokeSpecial:     return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
          case REF_newInvokeSpecial:  return this;
          }
          throw new IllegalArgumentException(this.toString());

@@ -671,13 +695,18 @@
      public MemberName(Constructor<?> ctor) {
          Objects.requireNonNull(ctor);
          // fill in vmtarget, vmindex while we have ctor in hand:
          MethodHandleNatives.init(this, ctor);
          assert(isResolved() && this.clazz != null);
-         this.name = CONSTRUCTOR_NAME;
-         if (this.type == null)
-             this.type = new Object[] { void.class, ctor.getParameterTypes() };
+         this.name = this.clazz.isValue() ? VALUE_FACTORY_NAME : CONSTRUCTOR_NAME;
+         if (this.type == null) {
+             Class<?> rtype = void.class;
+             if (isStatic()) {  // a value class static factory, not a true constructor
+                 rtype = getDeclaringClass();
+             }
+             this.type = new Object[] { rtype, ctor.getParameterTypes() };
+         }
      }
      /** Create a name for the given reflected field.  The resulting name will be in a resolved state.
       */
      public MemberName(Field fld) {
          this(fld, false);

@@ -808,17 +837,18 @@
          init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
          initResolved(false);
      }
      /** Create a method or constructor name from the given components:
       *  Declaring class, name, type, reference kind.
-      *  It will be a constructor if and only if the name is {@code "<init>"}.
+      *  It will be an object constructor if and only if the name is {@code "<init>"}.
+      *  It will be a value class instance factory method if and only if the name is {@code "<vnew>"}.
       *  The declaring class may be supplied as null if this is to be a bare name and type.
       *  The last argument is optional, a boolean which requests REF_invokeSpecial.
       *  The resulting name will in an unresolved state.
       */
      public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
-         int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
+         int initFlags = CONSTRUCTOR_NAME.equals(name) ? IS_OBJECT_CONSTRUCTOR : IS_METHOD;
          init(defClass, name, type, flagsMods(initFlags, 0, refKind));
          initResolved(false);
      }
      /** Create a method, constructor, or field name from the given components:
       *  Reference kind, declaring class, name, type.

@@ -832,11 +862,11 @@
          } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
              kindFlags = IS_METHOD;
              if (!(type instanceof MethodType))
                  throw newIllegalArgumentException("not a method type");
          } else if (refKind == REF_newInvokeSpecial) {
-             kindFlags = IS_CONSTRUCTOR;
+             kindFlags = IS_OBJECT_CONSTRUCTOR;
              if (!(type instanceof MethodType) ||
                  !CONSTRUCTOR_NAME.equals(name))
                  throw newIllegalArgumentException("not a constructor type or name");
          } else {
              throw newIllegalArgumentException("bad reference kind "+refKind);

@@ -955,11 +985,11 @@
          return new IllegalAccessException(message);
      }
      private String message() {
          if (isResolved())
              return "no access";
-         else if (isConstructor())
+         else if (isObjectConstructor())
              return "no such constructor";
          else if (isMethod())
              return "no such method";
          else
              return "no such field";

@@ -968,11 +998,11 @@
          String message = message() + ": "+ toString();
          ReflectiveOperationException ex;
          if (isResolved() || !(resolution instanceof NoSuchMethodError ||
                                resolution instanceof NoSuchFieldError))
              ex = new IllegalAccessException(message);
-         else if (isConstructor())
+         else if (isObjectConstructor())
              ex = new NoSuchMethodException(message);
          else if (isMethod())
              ex = new NoSuchMethodException(message);
          else
              ex = new NoSuchFieldException(message);

@@ -1149,16 +1179,16 @@
          public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
                  String name, MethodType type, Class<?> lookupClass) {
              int matchFlags = IS_METHOD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
              return getMembers(defc, name, type, matchFlags, lookupClass);
          }
-         /** Return a list of all constructors defined by the given class.
+         /** Return a list of all object constructors defined by the given class.
           *  Access checking is performed on behalf of the given {@code lookupClass}.
           *  Inaccessible members are not added to the last.
           */
-         public List<MemberName> getConstructors(Class<?> defc, Class<?> lookupClass) {
-             return getMembers(defc, null, null, IS_CONSTRUCTOR, lookupClass);
+         public List<MemberName> getObjectConstructors(Class<?> defc, Class<?> lookupClass) {
+             return getMembers(defc, null, null, IS_OBJECT_CONSTRUCTOR, lookupClass);
          }
          /** Return a list of all fields defined by the given class.
           *  Super types are searched (for inherited members) if {@code searchSupers} is true.
           *  Access checking is performed on behalf of the given {@code lookupClass}.
           *  Inaccessible members are not added to the last.
< prev index next >