java.lang.invoke.MethodHandle.asSpreader()方法的使用及代码示例

x33g5p2x  于2022-01-24 转载在 其他  
字(11.0k)|赞(0)|评价(0)|浏览(124)

本文整理了Java中java.lang.invoke.MethodHandle.asSpreader()方法的一些代码示例,展示了MethodHandle.asSpreader()的具体用法。这些代码示例主要来源于Github/Stackoverflow/Maven等平台,是从一些精选项目中提取出来的代码,具有较强的参考意义,能在一定程度帮忙到你。MethodHandle.asSpreader()方法的具体详情如下:
包路径:java.lang.invoke.MethodHandle
类名称:MethodHandle
方法名:asSpreader

MethodHandle.asSpreader介绍

[英]Makes an array-spreading method handle, which accepts a trailing array argument and spreads its elements as positional arguments. The new method handle adapts, as its target, the current method handle. The type of the adapter will be the same as the type of the target, except that the final arrayLength parameters of the target's type are replaced by a single array parameter of type arrayType.

If the array element type differs from any of the corresponding argument types on the original target, the original target is adapted to take the array elements directly, as if by a call to #asType.

When called, the adapter replaces a trailing array argument by the array's elements, each as its own argument to the target. (The order of the arguments is preserved.) They are converted pairwise by casting and/or unboxing to the types of the trailing parameters of the target. Finally the target is called. What the target eventually returns is returned unchanged by the adapter.

Before calling the target, the adapter verifies that the array contains exactly enough elements to provide a correct argument count to the target method handle. (The array may also be null when zero elements are required.)

If, when the adapter is called, the supplied array argument does not have the correct number of elements, the adapter will throw an IllegalArgumentException instead of invoking the target.

Here are some simple examples of array-spreading method handles:

MethodHandle equals = publicLookup()assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" })); 
assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" })); 
// try to spread from anything but a 2-array: 
for (int n = 0; n  a : new Class[]{Object[].class, String[].class, CharSequence[].class})  
MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n); 
assert( (boolean) equals2.invokeWithArguments("me", "me")); 
assert(!(boolean) equals2.invokeWithArguments("me", "thee")); 
} 
} 
MethodHandle caToString = publicLookup() 
.findStatic(Arrays.class, "toString", methodType(String.class, char[].class)); 
assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray())); 
MethodHandle caString3 = caToString.asCollector(char[].class, 3); 
assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C')); 
MethodHandle caToString2 = caString3.asSpreader(char[].class, 2); 
assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray())); 
}

[中]生成一个数组扩展方法句柄,该句柄接受尾随数组参数并将其元素作为位置参数扩展。新方法句柄将当前方法句柄作为其目标进行调整。适配器的类型将与目标类型相同,只是目标类型的最终arrayLength参数将替换为arrayType类型的单个数组参数。
如果数组元素类型不同于原始目标上的任何相应参数类型,则原始目标将调整为直接获取数组元素,就像通过调用#asType一样。
调用时,适配器用数组的元素替换尾随的数组参数,每个元素都作为其对目标的参数。(参数的顺序将保留。)通过强制转换和/或取消装箱,将它们成对转换为目标的后续参数类型。最后,目标被调用。目标最终返回的内容由适配器原封不动地返回。
在调用目标之前,适配器验证数组是否包含足够的元素,以便为目标方法句柄提供正确的参数计数。(当需要零个元素时,数组也可能为空。)
如果在调用适配器时,提供的数组参数的元素数不正确,适配器将抛出IllegalArgumentException,而不是调用目标。
下面是数组扩展方法句柄的一些简单示例:

MethodHandle equals = publicLookup()assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" })); 
assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" })); 
// try to spread from anything but a 2-array: 
for (int n = 0; n  a : new Class[]{Object[].class, String[].class, CharSequence[].class})  
MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n); 
assert( (boolean) equals2.invokeWithArguments("me", "me")); 
assert(!(boolean) equals2.invokeWithArguments("me", "thee")); 
} 
} 
MethodHandle caToString = publicLookup() 
.findStatic(Arrays.class, "toString", methodType(String.class, char[].class)); 
assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray())); 
MethodHandle caString3 = caToString.asCollector(char[].class, 3); 
assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C')); 
MethodHandle caToString2 = caString3.asSpreader(char[].class, 2); 
assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray())); 
}

代码示例

代码示例来源:origin: org.codehaus.groovy/groovy

public void correctSpreading() {
  if (!spread || useMetaClass || skipSpreadCollector) return;
  handle = handle.asSpreader(Object[].class, args.length-1);
}

代码示例来源:origin: org.codehaus.groovy/groovy

/**
 * Core method for indy method selection using runtime types.
 */
public static Object selectMethod(MutableCallSite callSite, Class sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable {
  Selector selector = Selector.getSelector(callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, arguments); 
  selector.setCallSiteTarget();
  MethodHandle call = selector.handle.asSpreader(Object[].class, arguments.length);
  call = call.asType(MethodType.methodType(Object.class,Object[].class));
  return call.invokeExact(arguments);
}

代码示例来源:origin: eclipse/golo-lang

public FunctionReference asSpreader(Class<?> arrayType, int arrayLength) {
 return new FunctionReference(handle.asSpreader(arrayType, arrayLength));
}

代码示例来源:origin: com.headius/invokebinder

public MethodHandle up(MethodHandle target) {
  return target.asSpreader(source.parameterType(source.parameterCount() - 1), spreadTypes.length);
}

代码示例来源:origin: baratine/baratine

MethodStub_N(ServicesAmp rampManager,
         Method method)
  throws IllegalAccessException
{
 super(method);
 
 _actorName = method.getDeclaringClass().getSimpleName();
 
 Class<?> []paramTypes = method.getParameterTypes();
 method.setAccessible(true);
 MethodHandle mh = MethodHandles.lookup().unreflect(method);
 mh = mh.asType(MethodType.genericMethodType(paramTypes.length + 1));
 
 mh = filterMethod(rampManager,
          mh,
          method);
 
 mh = mh.asSpreader(Object[].class, paramTypes.length);
 MethodType type = MethodType.methodType(Object.class, 
                     Object.class,
                     Object[].class);
 _methodHandle = mh.asType(type);
}

代码示例来源:origin: eclipse/golo-lang

/**
 * Spread arguments over this function parameters.
 *
 * @param arguments arguments as an array.
 * @return a return value.
 * @throws Throwable ...because an exception can be thrown.
 */
public Object spread(Object... arguments) throws Throwable {
 int arity = arity();
 if (this.handle.isVarargsCollector() && (arity > 0) && (arguments[arity - 1] instanceof Object[])) {
  return this.handle
    .asFixedArity()
    .asSpreader(Object[].class, arguments.length)
    .invoke(arguments);
 }
 return this.handle
   .asSpreader(Object[].class, arguments.length)
   .invoke(arguments);
}

代码示例来源:origin: org.opendaylight.mdsal/mdsal-binding-dom-codec

static Callable<BitsCodec> loader(final Class<?> returnType, final BitsTypeDefinition rootType) {
  return () -> {
    final Map<String, Method> getters = new LinkedHashMap<>();
    final Set<String> ctorArgs = new TreeSet<>();
    for (Bit bit : rootType.getBits()) {
      final Method valueGetter = returnType.getMethod(BindingMapping.BOOLEAN_GETTER_PREFIX
        + BindingMapping.getClassName(bit.getName()));
      ctorArgs.add(bit.getName());
      getters.put(bit.getName(), valueGetter);
    }
    Constructor<?> constructor = null;
    for (Constructor<?> cst : returnType.getConstructors()) {
      if (!cst.getParameterTypes()[0].equals(returnType)) {
        constructor = cst;
      }
    }
    final MethodHandle ctor = MethodHandles.publicLookup().unreflectConstructor(constructor)
        .asSpreader(Boolean[].class, ctorArgs.size()).asType(CONSTRUCTOR_INVOKE_TYPE);
    return new BitsCodec(returnType, ctor, ctorArgs, getters);
  };
}

代码示例来源:origin: org.opendaylight.mdsal/mdsal-binding2-dom-codec

static Callable<BitsCodec> loader(final Class<?> returnType, final BitsTypeDefinition rootType) {
  return () -> {
    final Map<String, Method> getters = new LinkedHashMap<>();
    final Set<String> ctorArgs = new TreeSet<>();
    for (Bit bit : rootType.getBits()) {
      final Method valueGetter = returnType.getMethod("is" + JavaIdentifierNormalizer
          .normalizeSpecificIdentifier(bit.getName(), JavaIdentifier.CLASS));
      ctorArgs.add(bit.getName());
      getters.put(bit.getName(), valueGetter);
    }
    Constructor<?> constructor = null;
    for (Constructor<?> cst : returnType.getConstructors()) {
      if (!cst.getParameterTypes()[0].equals(returnType)) {
        constructor = cst;
      }
    }
    final MethodHandle ctor = MethodHandles.publicLookup().unreflectConstructor(constructor)
        .asSpreader(Boolean[].class, ctorArgs.size()).asType(CONSTRUCTOR_INVOKE_TYPE);
    return new BitsCodec(returnType, ctor, ctorArgs, getters);
  };
}

代码示例来源:origin: skadistats/clarity

@Override
public void bind(Context ctx) throws IllegalAccessException {
  log.debug("bind %s to context", method);
  MethodHandle boundHandle = MethodHandles.publicLookup().unreflect(method).bindTo(ctx.getProcessor(processorClass));
  if (hasContextParameter()) {
    boundHandle = boundHandle.bindTo(ctx);
  }
  this.methodHandle = boundHandle.asSpreader(Object[].class, arity);
}

代码示例来源:origin: com.skadistats/clarity

@Override
public void bind(Context ctx) throws IllegalAccessException {
  log.debug("bind %s to context", method);
  MethodHandle boundHandle = MethodHandles.publicLookup().unreflect(method).bindTo(ctx.getProcessor(processorClass));
  if (hasContextParameter()) {
    boundHandle = boundHandle.bindTo(ctx);
  }
  this.methodHandle = boundHandle.asSpreader(Object[].class, arity);
}

代码示例来源:origin: baratine/baratine

mh = mh.asSpreader(Object[].class, paramTypes.length - 1);

代码示例来源:origin: baratine/baratine

mh = mh.asSpreader(Object[].class, paramLen - 1);

代码示例来源:origin: com.oracle.truffle/truffle-api

protected static MethodHandle adaptSignature(MethodHandle originalHandle, boolean isStatic, int parameterCount) {
    MethodHandle adaptedHandle = originalHandle;
    adaptedHandle = adaptedHandle.asType(adaptedHandle.type().changeReturnType(Object.class));
    if (isStatic) {
      adaptedHandle = MethodHandles.dropArguments(adaptedHandle, 0, Object.class);
    } else {
      adaptedHandle = adaptedHandle.asType(adaptedHandle.type().changeParameterType(0, Object.class));
    }
    adaptedHandle = adaptedHandle.asSpreader(Object[].class, parameterCount);
    return adaptedHandle;
  }
}

代码示例来源:origin: org.graalvm.truffle/truffle-api

protected static MethodHandle adaptSignature(MethodHandle originalHandle, boolean isStatic, int parameterCount) {
    MethodHandle adaptedHandle = originalHandle;
    adaptedHandle = adaptedHandle.asType(adaptedHandle.type().changeReturnType(Object.class));
    if (isStatic) {
      adaptedHandle = MethodHandles.dropArguments(adaptedHandle, 0, Object.class);
    } else {
      adaptedHandle = adaptedHandle.asType(adaptedHandle.type().changeParameterType(0, Object.class));
    }
    adaptedHandle = adaptedHandle.asSpreader(Object[].class, parameterCount);
    return adaptedHandle;
  }
}

代码示例来源:origin: com.ning.billing/killbill-osgi-bundles-jruby

if (argCount > 3) {
  nativeTarget = nativeTarget.asSpreader(IRubyObject[].class, argCount);

代码示例来源:origin: org.kill-bill.billing/killbill-osgi-bundles-jruby

if (argCount > 3) {
  nativeTarget = nativeTarget.asSpreader(IRubyObject[].class, argCount);

代码示例来源:origin: com.ning.billing/killbill-osgi-bundles-jruby

isTrue = isTrue.asSpreader(IRubyObject[].class, signature.getParameterCount());

代码示例来源:origin: org.kill-bill.billing/killbill-osgi-bundles-jruby

isTrue = isTrue.asSpreader(IRubyObject[].class, signature.getParameterCount());

代码示例来源:origin: com.ning.billing/killbill-osgi-bundles-jruby

targetHandle = targetHandle.asSpreader(IRubyObject[].class, signature.getParameterCount());

代码示例来源:origin: org.kill-bill.billing/killbill-osgi-bundles-jruby

targetHandle = targetHandle.asSpreader(IRubyObject[].class, signature.getParameterCount());

相关文章