< prev index next > src/java.base/share/classes/java/lang/invoke/MemberName.java
Print this page
* questions.
*/
package java.lang.invoke;
+ import jdk.internal.value.PrimitiveClass;
import sun.invoke.util.VerifyAccess;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
}
/** 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>"}.
*/
public String getName() {
if (name == null) {
expandFromVM();
if (name == null) {
}
/** 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 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) {
* 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);
if (!isStatic())
! return itype.insertParameterTypes(0, clazz);
return itype;
}
/** Return the declared type of this member, which
* must be a field or type.
* 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();
! Class<?> c = PrimitiveClass.isPrimitiveClass(clazz) ? PrimitiveClass.asValueType(clazz) : clazz;
! if (isObjectConstructor() && getReferenceKind() == REF_newInvokeSpecial)
+ return itype.changeReturnType(c);
if (!isStatic())
! return itype.insertParameterTypes(0, c);
return itype;
}
/** Return the declared type of this member, which
* must be a field or type.
byte refKind = getReferenceKind();
if (refKind == REF_NONE) return isType();
if (isField()) {
assert(staticIsConsistent());
assert(MethodHandleNatives.refKindIsField(refKind));
! } else if (isConstructor()) {
assert(refKind == REF_newInvokeSpecial || refKind == REF_invokeSpecial);
} else if (isMethod()) {
assert(staticIsConsistent());
assert(MethodHandleNatives.refKindIsMethod(refKind));
if (clazz.isInterface())
byte refKind = getReferenceKind();
if (refKind == REF_NONE) return isType();
if (isField()) {
assert(staticIsConsistent());
assert(MethodHandleNatives.refKindIsField(refKind));
! } else if (isObjectConstructor()) {
assert(refKind == REF_newInvokeSpecial || refKind == REF_invokeSpecial);
} else if (isMethod()) {
assert(staticIsConsistent());
assert(MethodHandleNatives.refKindIsMethod(refKind));
if (clazz.isInterface())
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());
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;
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
public boolean isBridge() {
return allFlagsSet(IS_METHOD | BRIDGE);
}
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
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;
+
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
public boolean isBridge() {
return allFlagsSet(IS_METHOD | BRIDGE);
}
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
public boolean isSynthetic() {
return allFlagsSet(SYNTHETIC);
}
! static final String CONSTRUCTOR_NAME = "<init>"; // 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
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;
/** Utility method to query whether this member is a method or constructor. */
public boolean isInvocable() {
return anyFlagSet(IS_INVOCABLE);
}
/** Query whether this member is a method. */
public boolean isMethod() {
return allFlagsSet(IS_METHOD);
}
/** Query whether this member is a constructor. */
! public boolean isConstructor() {
! return allFlagsSet(IS_CONSTRUCTOR);
}
/** Query whether this member is a field. */
public boolean isField() {
return allFlagsSet(IS_FIELD);
}
/** Query whether this member is a type. */
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
public boolean isSynthetic() {
return allFlagsSet(SYNTHETIC);
}
! /** 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 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_OBJECT_CONSTRUCTOR | IS_FIELD | IS_TYPE;
! static final int IS_INVOCABLE = IS_METHOD | IS_OBJECT_CONSTRUCTOR;
/** Utility method to query whether this member is a method or constructor. */
public boolean isInvocable() {
return anyFlagSet(IS_INVOCABLE);
}
/** Query whether this member is a method. */
public boolean isMethod() {
return allFlagsSet(IS_METHOD);
}
/** Query whether this member is a constructor. */
! public boolean isObjectConstructor() {
! return allFlagsSet(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 allFlagsSet(IS_FIELD);
}
/** Query whether this member is a type. */
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() {
switch (getReferenceKind()) {
case REF_invokeSpecial: return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
case REF_newInvokeSpecial: return this;
}
throw new IllegalArgumentException(this.toString());
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 asObjectConstructor() {
switch (getReferenceKind()) {
case REF_invokeSpecial: return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
case REF_newInvokeSpecial: return this;
}
throw new IllegalArgumentException(this.toString());
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() };
}
/** Create a name for the given reflected field. The resulting name will be in a resolved state.
*/
public MemberName(Field fld) {
this(fld, false);
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 = 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);
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>"}.
* 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);
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.
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 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 = 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.
} 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;
if (!(type instanceof MethodType) ||
!CONSTRUCTOR_NAME.equals(name))
throw newIllegalArgumentException("not a constructor type or name");
} else {
throw newIllegalArgumentException("bad reference kind "+refKind);
} 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_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);
return new IllegalAccessException(message);
}
private String message() {
if (isResolved())
return "no access";
! else if (isConstructor())
return "no such constructor";
else if (isMethod())
return "no such method";
else
return "no such field";
return new IllegalAccessException(message);
}
private String message() {
if (isResolved())
return "no access";
! else if (isObjectConstructor())
return "no such constructor";
else if (isMethod())
return "no such method";
else
return "no such field";
String message = message() + ": " + this;
ReflectiveOperationException ex;
if (isResolved() || !(resolution instanceof NoSuchMethodError ||
resolution instanceof NoSuchFieldError))
ex = new IllegalAccessException(message);
! else if (isConstructor())
ex = new NoSuchMethodException(message);
else if (isMethod())
ex = new NoSuchMethodException(message);
else
ex = new NoSuchFieldException(message);
String message = message() + ": " + this;
ReflectiveOperationException ex;
if (isResolved() || !(resolution instanceof NoSuchMethodError ||
resolution instanceof NoSuchFieldError))
ex = new IllegalAccessException(message);
! else if (isObjectConstructor())
ex = new NoSuchMethodException(message);
else if (isMethod())
ex = new NoSuchMethodException(message);
else
ex = new NoSuchFieldException(message);
< prev index next >