下面列出了java.lang.invoke.MethodType#parameterArray ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private MethodType explicitParams(final MethodType callSiteType) {
if (CompiledFunction.isVarArgsType(callSiteType)) {
return null;
}
final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
final int callSiteParamCount = noCalleeThisType.parameterCount();
// Widen parameters of reference types to Object as we currently don't care for specialization among reference
// types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
boolean changed = false;
for (int i = 0; i < paramTypes.length; ++i) {
final Class<?> paramType = paramTypes[i];
if (!(paramType.isPrimitive() || paramType == Object.class)) {
paramTypes[i] = Object.class;
changed = true;
}
}
final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;
if (callSiteParamCount < getArity()) {
return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
}
return generalized;
}
private MethodType explicitParams(final MethodType callSiteType) {
if (CompiledFunction.isVarArgsType(callSiteType)) {
return null;
}
final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
final int callSiteParamCount = noCalleeThisType.parameterCount();
// Widen parameters of reference types to Object as we currently don't care for specialization among reference
// types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
boolean changed = false;
for (int i = 0; i < paramTypes.length; ++i) {
final Class<?> paramType = paramTypes[i];
if (!(paramType.isPrimitive() || paramType == Object.class)) {
paramTypes[i] = Object.class;
changed = true;
}
}
final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;
if (callSiteParamCount < getArity()) {
return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
}
return generalized;
}
private MethodType explicitParams(final MethodType callSiteType) {
if (CompiledFunction.isVarArgsType(callSiteType)) {
return null;
}
final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
final int callSiteParamCount = noCalleeThisType.parameterCount();
// Widen parameters of reference types to Object as we currently don't care for specialization among reference
// types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
boolean changed = false;
for (int i = 0; i < paramTypes.length; ++i) {
final Class<?> paramType = paramTypes[i];
if (!(paramType.isPrimitive() || paramType == Object.class)) {
paramTypes[i] = Object.class;
changed = true;
}
}
final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;
if (callSiteParamCount < getArity()) {
return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
}
return generalized;
}
private static MethodHandle convertArguments(MethodHandle handle, int fixedArguments, boolean varargs,
Converter converter) {
MethodType type = handle.type();
int pcount = type.parameterCount();
int actual = pcount - fixedArguments - (varargs ? 1 : 0);
Class<?>[] params = type.parameterArray();
MethodHandle[] filters = new MethodHandle[pcount];
for (int p = 0; p < actual; ++p) {
filters[fixedArguments + p] = converter.filterFor(params[fixedArguments + p]);
}
if (varargs) {
filters[pcount - 1] = converter.arrayFilterFor(params[pcount - 1]);
}
handle = MethodHandles.filterArguments(handle, 0, filters);
return handle;
}
private MethodType explicitParams(final MethodType callSiteType) {
if (CompiledFunction.isVarArgsType(callSiteType)) {
return null;
}
final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
final int callSiteParamCount = noCalleeThisType.parameterCount();
// Widen parameters of reference types to Object as we currently don't care for specialization among reference
// types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
boolean changed = false;
for (int i = 0; i < paramTypes.length; ++i) {
final Class<?> paramType = paramTypes[i];
if (!(paramType.isPrimitive() || paramType == Object.class)) {
paramTypes[i] = Object.class;
changed = true;
}
}
final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;
if (callSiteParamCount < getArity()) {
return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
}
return generalized;
}
/**
* Helper method to manipulate the given type to replace Wrapper with Object.
*/
private MethodType removeWrapper(MethodType targetType) {
Class<?>[] types = targetType.parameterArray();
for (int i = 0; i < types.length; i++) {
if (types[i] == Wrapper.class) {
targetType = targetType.changeParameterType(i, Object.class);
}
}
return targetType;
}
/**
* Test of parameterArray method, of class MethodType.
*/
@Test
public void testParameterArray() {
System.out.println("parameterArray");
MethodType instance = mt_viS;
Class<?>[] expResult = ptypes;
Class<?>[] result = instance.parameterArray();
assertEquals(Arrays.asList(expResult), Arrays.asList(result));
}
/**
* Test of parameterArray method, of class MethodType.
*/
@Test
public void testParameterArray() {
System.out.println("parameterArray");
MethodType instance = mt_viS;
Class<?>[] expResult = ptypes;
Class<?>[] result = instance.parameterArray();
assertEquals(Arrays.asList(expResult), Arrays.asList(result));
}
/**
* Test of parameterArray method, of class MethodType.
*/
@Test
public void testParameterArray() {
System.out.println("parameterArray");
MethodType instance = mt_viS;
Class<?>[] expResult = ptypes;
Class<?>[] result = instance.parameterArray();
assertEquals(Arrays.asList(expResult), Arrays.asList(result));
}
static MethodHandle createUniversal(final String className, final String methodName, final Class<?> ...params)
throws IllegalAccessException, NoSuchMethodException, ClassNotFoundException {
final MethodHandle h = create(className, methodName, params);
final MethodType mt = h.type();
final Class<?>[] parameterArray = mt.parameterArray();
final Class<?>[] adaptedParameterArray = new Class<?>[parameterArray.length];
Arrays.fill(adaptedParameterArray, Object.class);
final MethodType adaptedMt = MethodType.methodType(Object.class, adaptedParameterArray);
return h.asType(adaptedMt);
}
/**
* Constructor
* @param functionNodeId function node id
* @param type method type found at runtime corresponding to parameter guess
* @param needsCallee does the function using this type map need a callee
*/
public TypeMap(final int functionNodeId, final MethodType type, final boolean needsCallee) {
final Type[] types = new Type[type.parameterCount()];
int pos = 0;
for (final Class<?> p : type.parameterArray()) {
types[pos++] = Type.typeFor(p);
}
this.functionNodeId = functionNodeId;
this.paramTypes = types;
this.returnType = Type.typeFor(type.returnType());
this.needsCallee = needsCallee;
}
public static CallSite metafactory(Lookup lookup, String name, MethodType type,
MethodType sig, MethodHandle impl, MethodType reifiedSig) throws Throwable {
Class<?>[] capturedTypes = type.parameterArray();
MethodHandle target = impl.asType(reifiedSig.insertParameterTypes(0, capturedTypes)); // apply generic casts
MethodHandle mh = Proxy2.createAnonymousProxyFactory(lookup, type, new LambdaProxyHandler(target, capturedTypes));
if (type.parameterCount() == 0) { // no capture
return new ConstantCallSite(MethodHandles.constant(type.returnType(), mh.invoke()));
}
return new ConstantCallSite(mh);
}
/**
* Constructor
* @param functionNodeId function node id
* @param type method type found at runtime corresponding to parameter guess
* @param needsCallee does the function using this type map need a callee
*/
public TypeMap(final int functionNodeId, final MethodType type, final boolean needsCallee) {
final Type[] types = new Type[type.parameterCount()];
int pos = 0;
for (final Class<?> p : type.parameterArray()) {
types[pos++] = Type.typeFor(p);
}
this.functionNodeId = functionNodeId;
this.paramTypes = types;
this.returnType = Type.typeFor(type.returnType());
this.needsCallee = needsCallee;
}
/**
* Test of parameterArray method, of class MethodType.
*/
@Test
public void testParameterArray() {
System.out.println("parameterArray");
MethodType instance = mt_viS;
Class<?>[] expResult = ptypes;
Class<?>[] result = instance.parameterArray();
assertEquals(Arrays.asList(expResult), Arrays.asList(result));
}
/**
* Test of parameterArray method, of class MethodType.
*/
@Test
public void testParameterArray() {
System.out.println("parameterArray");
MethodType instance = mt_viS;
Class<?>[] expResult = ptypes;
Class<?>[] result = instance.parameterArray();
assertEquals(Arrays.asList(expResult), Arrays.asList(result));
}
ClassString(final MethodType type) {
this(type.parameterArray());
}
private static MethodHandle getStaticMethodHandle(Lookup lookup, Method method) throws IllegalAccessException {
MethodHandle handle = lookup.unreflect(method);
MethodType type = handle.type();
Class<?>[] params = type.parameterArray();
int p = 0, pcount = type.parameterCount();
boolean callerContext = false;
// First three parameters are (ExecutionContext, ExecutionContext?, Object=ThisValue)
if (!(p < pcount && ExecutionContext.class.equals(params[p++]))) {
throw new IllegalArgumentException(type.toString());
}
if (p < pcount && ExecutionContext.class.equals(params[p])) {
callerContext = true;
p++;
}
if (!(p < pcount && Object.class.equals(params[p++]))) {
throw new IllegalArgumentException(type.toString());
}
// Always required to return Object (for now at least)
if (!Object.class.equals(type.returnType())) {
throw new IllegalArgumentException(type.toString());
}
// Collect remaining arguments into Object[]
if (!(p + 1 == pcount && Object[].class.equals(params[p]))) {
final int fixedArguments = callerContext ? 3 : 2;
final boolean varargs = handle.isVarargsCollector();
// Otherwise all trailing arguments need to be of type Object or Object[]
for (; p < pcount; ++p) {
if (Object.class.equals(params[p])) {
continue;
}
if (p + 1 == pcount && Object[].class.equals(params[p]) && varargs) {
continue;
}
throw new IllegalArgumentException(type.toString());
}
// Trailing Object[] arguments are no longer spread in var-args methods (jdk8u40, jdk9).
if (varargs) {
handle = handle.asFixedArity();
}
// Convert to (ExecutionContext, Object, ...) -> Object handle
handle = toCanonical(handle, fixedArguments, varargs, method);
}
if (!callerContext) {
handle = MethodHandles.dropArguments(handle, 1, ExecutionContext.class);
}
// assert handle.type().parameterCount() == 4;
// assert handle.type().parameterType(0) == ExecutionContext.class;
// assert handle.type().parameterType(1) == ExecutionContext.class;
// assert handle.type().parameterType(2) == Object.class;
// assert handle.type().parameterType(3) == Object[].class;
// assert handle.type().returnType() == Object.class;
return handle;
}
ClassString(final MethodType type) {
this(type.parameterArray());
}
ClassString(final MethodType type) {
this(type.parameterArray());
}
ClassString(final MethodType type) {
this(type.parameterArray());
}