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

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

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

MethodHandle.asCollector介绍

[英]Makes an array-collecting method handle, which accepts a given number of trailing positional arguments and collects them into an array argument. 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 a single trailing parameter (usually of type arrayType) is replaced by arrayLength parameters whose type is element type of arrayType.

If the array type differs from the final argument type on the original target, the original target is adapted to take the array type directly, as if by a call to #asType.

When called, the adapter replaces its trailing arrayLengtharguments by a single new array of type arrayType, whose elements comprise (in order) the replaced arguments. Finally the target is called. What the target eventually returns is returned unchanged by the adapter.

(The array may also be a shared constant when arrayLength is zero.)

(Note: The arrayType is often identical to the last parameter type of the original target. It is an explicit argument for symmetry with asSpreader, and also to allow the target to use a simple Object as its last parameter type.)

In order to create a collecting adapter which is not restricted to a particular number of collected arguments, use #asVarargsCollector instead.

Here are some examples of array-collecting method handles:

MethodHandle deepToString = publicLookup()assertEquals("[won]",   (String) deepToString.invokeExact(new Object[]{"won"})); 
MethodHandle ts1 = deepToString.asCollector(Object[].class, 1); 
assertEquals(methodType(String.class, Object.class), ts1.type()); 
//assertEquals("[won]", (String) ts1.invokeExact(         new Object[]{"won"})); //FAIL 
assertEquals("[[won]]", (String) ts1.invokeExact((Object) new Object[]{"won"})); 
// arrayType can be a subtype of Object[] 
MethodHandle ts2 = deepToString.asCollector(String[].class, 2); 
assertEquals(methodType(String.class, String.class, String.class), ts2.type()); 
assertEquals("[two, too]", (String) ts2.invokeExact("two", "too")); 
MethodHandle ts0 = deepToString.asCollector(Object[].class, 0); 
assertEquals("[]", (String) ts0.invokeExact()); 
// collectors can be nested, Lisp-style 
MethodHandle ts22 = deepToString.asCollector(Object[].class, 3).asCollector(String[].class, 2); 
assertEquals("[A, B, [C, D]]", ((String) ts22.invokeExact((Object)'A', (Object)"B", "C", "D"))); 
// arrayType can be any primitive array type 
MethodHandle bytesToString = publicLookup() 
.findStatic(Arrays.class, "toString", methodType(String.class, byte[].class)) 
.asCollector(byte[].class, 3); 
assertEquals("[1, 2, 3]", (String) bytesToString.invokeExact((byte)1, (byte)2, (byte)3)); 
MethodHandle longsToString = publicLookup() 
.findStatic(Arrays.class, "toString", methodType(String.class, long[].class)) 
.asCollector(long[].class, 1); 
assertEquals("[123]", (String) longsToString.invokeExact((long)123)); 
}

[中]生成一个array collecting方法句柄,该句柄接受给定数量的尾随位置参数,并将它们收集到一个数组参数中。新方法句柄将当前方法句柄作为其目标进行调整。适配器的类型将与目标的类型相同,只是单个尾随参数(通常为arrayType类型)被arrayLength参数替换,其类型为arrayType的元素类型。
如果数组类型与原始目标上的最终参数类型不同,则原始目标将调整为直接获取数组类型,就像通过调用#asType一样。
调用时,适配器将其尾部的arrayLengtharguments替换为arrayType类型的单个新数组,其元素(按顺序)包含替换的参数。最后,目标被调用。目标最终返回的内容由适配器原封不动地返回。
(当arrayLength为零时,数组也可以是共享常量。)
(*注意:*arrayType通常与原始目标的最后一个参数类型相同。它是asSpreader对称性的显式参数,也允许目标使用简单对象作为其最后一个参数类型。)
为了创建不限于特定数量的收集参数的收集适配器,请改用#asVarargsCollector。
以下是一些数组收集方法句柄的示例:

MethodHandle deepToString = publicLookup()assertEquals("[won]",   (String) deepToString.invokeExact(new Object[]{"won"})); 
MethodHandle ts1 = deepToString.asCollector(Object[].class, 1); 
assertEquals(methodType(String.class, Object.class), ts1.type()); 
//assertEquals("[won]", (String) ts1.invokeExact(         new Object[]{"won"})); //FAIL 
assertEquals("[[won]]", (String) ts1.invokeExact((Object) new Object[]{"won"})); 
// arrayType can be a subtype of Object[] 
MethodHandle ts2 = deepToString.asCollector(String[].class, 2); 
assertEquals(methodType(String.class, String.class, String.class), ts2.type()); 
assertEquals("[two, too]", (String) ts2.invokeExact("two", "too")); 
MethodHandle ts0 = deepToString.asCollector(Object[].class, 0); 
assertEquals("[]", (String) ts0.invokeExact()); 
// collectors can be nested, Lisp-style 
MethodHandle ts22 = deepToString.asCollector(Object[].class, 3).asCollector(String[].class, 2); 
assertEquals("[A, B, [C, D]]", ((String) ts22.invokeExact((Object)'A', (Object)"B", "C", "D"))); 
// arrayType can be any primitive array type 
MethodHandle bytesToString = publicLookup() 
.findStatic(Arrays.class, "toString", methodType(String.class, byte[].class)) 
.asCollector(byte[].class, 3); 
assertEquals("[1, 2, 3]", (String) bytesToString.invokeExact((byte)1, (byte)2, (byte)3)); 
MethodHandle longsToString = publicLookup() 
.findStatic(Arrays.class, "toString", methodType(String.class, long[].class)) 
.asCollector(long[].class, 1); 
assertEquals("[123]", (String) longsToString.invokeExact((long)123)); 
}

代码示例

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

/**
   * Set MOP based constructor invocation path.
   */
  @Override
  public void setMetaClassCallHandleIfNedded(boolean standardMetaClass) {
    if (handle!=null) return;
    useMetaClass = true;
    if (LOG_ENABLED) LOG.info("set meta class invocation path");
    handle = MOP_INVOKE_CONSTRUCTOR.bindTo(mc);
    handle = handle.asCollector(Object[].class, targetType.parameterCount()-1);
    handle = MethodHandles.dropArguments(handle, 0, Class.class);
    if (LOG_ENABLED) LOG.info("create collector for arguments");
  }
}

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

/**
 * Sets a handle to call {@link GroovyInterceptable#invokeMethod(String, Object)}
 */
public boolean setInterceptor() {
  if (!(this.args[0] instanceof GroovyInterceptable)) return false;
  handle = MethodHandles.insertArguments(INTERCEPTABLE_INVOKER, 1, this.name);
  handle = handle.asCollector(Object[].class, targetType.parameterCount()-1); 
  handle = handle.asType(targetType);
  return true;
}

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

handle = handle.asCollector(lastParam, 1);
} else if (params.length > args.length) {
  handle = handle.asCollector(
      lastParam,
      args.length - params.length + 1);

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

/**
 * Makes a fallback method for an invalidated method selection
 */
protected static MethodHandle makeFallBack(MutableCallSite mc, Class<?> sender, String name, int callID, MethodType type, boolean safeNavigation, boolean thisCall, boolean spreadCall) {
  MethodHandle mh = MethodHandles.insertArguments(SELECT_METHOD, 0, mc, sender, name, callID, safeNavigation, thisCall, spreadCall, /*dummy receiver:*/ 1);
  mh =    mh.asCollector(Object[].class, type.parameterCount()).
      asType(type);
  return mh;
}

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

/**
 * Creates a MethodHandle, which will use the meta class path.
 * This method is called only if no handle has been created before. This
 * is usually the case if the method selection failed.
 */
public void setMetaClassCallHandleIfNedded(boolean standardMetaClass) {
  if (handle!=null) return;
  useMetaClass = true;
  if (LOG_ENABLED) LOG.info("set meta class invocation path");
  Object receiver = getCorrectedReceiver();
  if (receiver instanceof Class) {
    handle = META_CLASS_INVOKE_STATIC_METHOD.bindTo(mc);
    if (LOG_ENABLED) LOG.info("use invokeStaticMethod with bound meta class");
  } else {
    handle = MOP_INVOKE_METHOD.bindTo(mc);
    if (LOG_ENABLED) LOG.info("use invokeMethod with bound meta class");
    if (receiver instanceof GroovyObject) {
      // if the meta class call fails we may still want to fall back to call
      // GroovyObject#invokeMethod if the receiver is a GroovyObject
      if (LOG_ENABLED) LOG.info("add MissingMethod handler for GrooObject#invokeMethod fallback path");
      handle = MethodHandles.catchException(handle, MissingMethodException.class, GROOVY_OBJECT_INVOKER);
    }
  }
  handle = MethodHandles.insertArguments(handle, 1, name);
  if (!spread) handle = handle.asCollector(Object[].class, targetType.parameterCount()-1);
  if (LOG_ENABLED) LOG.info("bind method name and create collector for arguments");
}

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

@Override public MethodHandle findShadowMethodHandle(Class<?> theClass, String name, MethodType type,
  boolean isStatic) throws IllegalAccessException {
 String signature = getSignature(theClass, name, type, isStatic);
 InvocationProfile invocationProfile = new InvocationProfile(signature, isStatic, getClass().getClassLoader());
 try {
  MethodHandle mh = MethodHandles.lookup().findVirtual(getClass(), "invoke",
    methodType(Object.class, InvocationProfile.class, Object.class, Object[].class));
  mh = insertArguments(mh, 0, this, invocationProfile);
  if (isStatic) {
   return mh.bindTo(null).asCollector(Object[].class, type.parameterCount());
  } else {
   return mh.asCollector(Object[].class, type.parameterCount() - 1);
  }
 } catch (NoSuchMethodException e) {
  throw new AssertionError(e);
 }
}

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

} else {
  handle = handle.asCollector(Object[].class, targetType.parameterCount()-1);

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

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

代码示例来源:origin: anba/es6draft

private static MethodHandle toObjectArray(List<Class<?>> types) {
  MethodHandle mh = MethodHandles.identity(Object[].class);
  mh = mh.asCollector(Object[].class, types.size());
  return mh.asType(MethodType.methodType(Object[].class, types));
}

代码示例来源:origin: anba/es6draft

public static CallSite runtimeBootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
  assert "rt:stack".equals(name) || "rt:locals".equals(name);
  MethodHandle mh = MethodHandles.identity(Object[].class);
  mh = mh.asCollector(Object[].class, type.parameterCount());
  mh = mh.asType(type);
  return new ConstantCallSite(mh);
}

代码示例来源:origin: gravel-st/gravel

public MethodHandle wrapDNUHandle(MethodHandle dnuHandle) {
  Symbol sym = selectorConverter.functionNameAsSelector_(selector);
  MethodHandle withBoundSymbol = MethodHandles.insertArguments(dnuHandle,
      1, sym);
  MethodHandle message = withBoundSymbol.asCollector(Object[].class,
      numArgs());
  return message;
}

代码示例来源:origin: org.dynalang/dynalink

/**
 * Creates a method handle out of the original target that will collect the varargs for the exact component type of
 * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs
 * for which it is necessary when later passed to linkerServices.convertArguments().
 *
 * @param target the original method handle
 * @param parameterCount the total number of arguments in the new method handle
 * @return a collecting method handle
 */
static MethodHandle collectArguments(MethodHandle target, final int parameterCount) {
  final MethodType methodType = target.type();
  final int fixParamsLen = methodType.parameterCount() - 1;
  final Class<?> arrayType = methodType.parameterType(fixParamsLen);
  return target.asCollector(arrayType, parameterCount - fixParamsLen);
}

代码示例来源:origin: org.codelibs.elasticsearch.module/lang-painless

MIC(String name, MethodType type, int initialDepth, int flavor, int flags) {
  super(type);
  this.name = name;
  this.flavor = flavor;
  this.flags = flags;
  if (initialDepth > 0) {
    initialized = true;
  }
  MethodHandle fallback = FALLBACK.bindTo(this)
   .asCollector(Object[].class, type.parameterCount())
   .asType(type);
  setTarget(fallback);
}

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

public static CallSite bootstrap(Lookup caller, String name, MethodType type, Object... bsmArgs) {
 boolean nullSafeGuarded = ((int) bsmArgs[0]) == 1;
 String[] argumentNames = new String[bsmArgs.length - 1];
 for (int i = 0; i < bsmArgs.length - 1; i++) {
  argumentNames[i] = (String) bsmArgs[i + 1];
 }
 InlineCache callSite = new InlineCache(caller, name, type, nullSafeGuarded, argumentNames);
 MethodHandle fallbackHandle = FALLBACK
   .bindTo(callSite)
   .asCollector(Object[].class, type.parameterCount())
   .asType(type);
 callSite.resetFallback = RESET_FALLBACK
   .bindTo(callSite)
   .asCollector(Object[].class, type.parameterCount())
   .asType(type);
 callSite.setTarget(fallbackHandle);
 return callSite;
}

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

public static CallSite bootstrap(Lookup caller, String name, MethodType type) {
 AdapterCallSite callSite = new AdapterCallSite(type, caller, name);
 MethodHandle fallbackHandle = FALLBACK
   .bindTo(callSite)
   .asCollector(Object[].class, type.parameterCount())
   .asType(type);
 callSite.setTarget(fallbackHandle);
 return callSite;
}

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

public MethodHandle up(MethodHandle target) {
  if (onlyTail()) {
    // fast path for tail args
    return target.asCollector(arrayType, count);
  } else {
    Permutes permutes = buildPermutes(source, target.type());
    Binder binder = preparePermuteBinder(permutes);
    return binder.invoke(target);
  }
}

代码示例来源:origin: szegedi/dynalink

private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) {
  // Make a bound MH of invoke() for this linker and call site
  final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf(
      relinkCount));
  // Make a MH that gathers all arguments to the invocation into an Object[]
  final MethodType type = callSite.getDescriptor().getMethodType();
  final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount());
  return MethodHandles.foldArguments(MethodHandles.exactInvoker(type), collectingRelinker.asType(
      type.changeReturnType(MethodHandle.class)));
}

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

public static CallSite bootstrap(Lookup caller, String name, MethodType type, Object... bsmArgs) {
 boolean constant = ((int) bsmArgs[0]) == 1;
 String[] argumentNames = new String[bsmArgs.length - 1];
 for (int i = 0; i < bsmArgs.length - 1; i++) {
  argumentNames[i] = (String) bsmArgs[i + 1];
 }
 InlineCache callSite = new InlineCache(type, constant, argumentNames);
 MethodHandle fallbackHandle = FALLBACK
   .bindTo(callSite)
   .asCollector(Object[].class, type.parameterCount())
   .asType(type);
 callSite.fallback = fallbackHandle;
 callSite.setTarget(fallbackHandle);
 return callSite;
}

代码示例来源:origin: org.dynalang/dynalink

private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, int relinkCount) {
  // Make a bound MH of invoke() for this linker and call site
  final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf(
      relinkCount));
  // Make a MH that gathers all arguments to the invocation into an Object[]
  final MethodType type = callSite.getDescriptor().getMethodType();
  final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount());
  return MethodHandles.foldArguments(MethodHandles.exactInvoker(type), collectingRelinker.asType(
      type.changeReturnType(MethodHandle.class)));
}

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

private static Object installVTableDispatch(InlineCache inlineCache, Object[] args) throws Throwable {
 if (inlineCache.vtable == null) {
  inlineCache.vtable = new WeakHashMap<>();
 }
 MethodHandle lookup = VTABLE_LOOKUP
   .bindTo(inlineCache)
   .asCollector(Object[].class, args.length);
 MethodHandle exactInvoker = exactInvoker(inlineCache.type());
 MethodHandle vtableTarget = foldArguments(exactInvoker, lookup);
 if (inlineCache.nullSafeGuarded) {
  vtableTarget = makeNullSafeGuarded(vtableTarget);
 }
 inlineCache.setTarget(vtableTarget);
 if (shouldReturnNull(inlineCache, args[0])) {
  return null;
 }
 return vtableTarget.invokeWithArguments(args);
}

相关文章