src/share/classes/java/lang/invoke/MethodType.java
Print this page
rev 8095 : JDK-8024635 v2
rev 8096 : JDK-8024635 v2
rev 8097 : JDK-8024635 v3
@@ -30,10 +30,11 @@
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
import sun.invoke.util.BytecodeDescriptor;
import static java.lang.invoke.MethodHandleStatics.*;
import sun.invoke.util.VerifyType;
@@ -95,18 +96,28 @@
// The remaining fields are caches of various sorts:
private MethodTypeForm form; // erased form, plus cached data about primitives
private MethodType wrapAlt; // alternative wrapped/unwrapped version
private Invokers invokers; // cache of handy higher-order adapters
+ private String methodDescriptor;
/**
* Check the given parameters for validity and store them into the final fields.
*/
- private MethodType(Class<?> rtype, Class<?>[] ptypes) {
+ private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
checkRtype(rtype);
checkPtypes(ptypes);
this.rtype = rtype;
+ // defensively copy the array passed in by the user
+ this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length);
+ }
+
+ /**
+ * Don't check the given parameters for validity - creates MethodType for usage as searching key only.
+ */
+ private MethodType(Class<?>[] ptypes, Class<?> rtype) {
+ this.rtype = rtype;
this.ptypes = ptypes;
}
/*trusted*/ MethodTypeForm form() { return form; }
/*trusted*/ Class<?> rtype() { return rtype; }
@@ -143,24 +154,25 @@
* {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
*/
/*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1; // deduct one more for invoker
private static void checkRtype(Class<?> rtype) {
- rtype.equals(rtype); // null check
+ Objects.requireNonNull(rtype);
}
- private static int checkPtype(Class<?> ptype) {
- ptype.getClass(); //NPE
+ private static void checkPtype(Class<?> ptype) {
+ Objects.requireNonNull(ptype);
if (ptype == void.class)
throw newIllegalArgumentException("parameter type cannot be void");
- if (ptype == double.class || ptype == long.class) return 1;
- return 0;
}
/** Return number of extra slots (count of long/double args). */
private static int checkPtypes(Class<?>[] ptypes) {
int slots = 0;
for (Class<?> ptype : ptypes) {
- slots += checkPtype(ptype);
+ checkPtype(ptype);
+ if (ptype == double.class || ptype == long.class) {
+ slots++;
+ }
}
checkSlotCount(ptypes.length + slots);
return slots;
}
static void checkSlotCount(int count) {
@@ -281,24 +293,20 @@
* @param trusted whether the ptypes can be used without cloning
* @return the unique method type of the desired structure
*/
/*trusted*/ static
MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
+ MethodType mt = internTable.get(new MethodType(ptypes, rtype));
+ if (mt != null)
+ return mt;
if (ptypes.length == 0) {
ptypes = NO_PTYPES; trusted = true;
}
- MethodType mt1 = new MethodType(rtype, ptypes);
- MethodType mt0 = internTable.get(mt1);
- if (mt0 != null)
- return mt0;
- if (!trusted)
- // defensively copy the array passed in by the user
- mt1 = new MethodType(rtype, ptypes.clone());
+ mt = new MethodType(rtype, ptypes, trusted);
// promote the object to the Real Thing, and reprobe
- MethodTypeForm form = MethodTypeForm.findForm(mt1);
- mt1.form = form;
- return internTable.add(mt1);
+ mt.form = MethodTypeForm.findForm(mt);
+ return internTable.add(mt);
}
private static final MethodType[] objectOnlyTypes = new MethodType[20];
/**
* Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
@@ -916,11 +924,16 @@
* {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
* because the latter requires a suitable class loader argument.
* @return the bytecode type descriptor representation
*/
public String toMethodDescriptorString() {
- return BytecodeDescriptor.unparse(this);
+ String desc = methodDescriptor;
+ if (desc == null) {
+ desc = BytecodeDescriptor.unparse(this);
+ methodDescriptor = desc;
+ }
+ return desc;
}
/*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
return BytecodeDescriptor.unparse(cls);
}