private TestCase(Class<T> rtype, Function<Object, T> cast, ThrowMode throwMode, Throwable thrown) throws NoSuchMethodException, IllegalAccessException { this.cast = cast; filter = MethodHandles.lookup() .findVirtual(Function.class, "apply", MethodType.methodType(Object.class, Object.class)) .bindTo(cast); this.rtype = rtype; this.throwMode = throwMode; this.throwableClass = thrown.getClass(); switch (throwMode) { case NOTHING: this.thrown = null; break; case ADAPTER: case UNCAUGHT: this.thrown = new Error("do not catch this"); break; default: this.thrown = thrown; } MethodHandle throwOrReturn = THROW_OR_RETURN; if (throwMode == ThrowMode.ADAPTER) { MethodHandle fakeIdentity = FAKE_IDENTITY.bindTo(this); for (int i = 0; i < 10; ++i) { throwOrReturn = MethodHandles.filterReturnValue(throwOrReturn, fakeIdentity); } } thrower = throwOrReturn.asType(MethodType.genericMethodType(2)); }
public static void main(String[] args) throws Throwable { Object x, y; String s; int i; MethodType mt; MethodHandle mh; MethodHandles.Lookup lookup = MethodHandles.lookup(); // mt is (char,char)String mt = MethodType.methodType(String.class, char.class, char.class); mh = lookup.findVirtual(String.class, "replace", mt); s = (String) mh.invokeExact("daddy", 'd', 'n'); System.out.println("Result: " + s); // invokeExact(Ljava/lang/String;CC)Ljava/lang/String; // weakly typed invocation (using MHs.invoke) s = (String) mh.invokeWithArguments("sappy", 'p', 'v'); System.out.println("Result: " + s); // mt is (Object[])List mt = MethodType.methodType(java.util.List.class, Object[].class); mh = lookup.findStatic(java.util.Arrays.class, "asList", mt); assert (mh.isVarargsCollector()); x = mh.invoke("one", "two"); // ArrayList System.out.println("x: " + x + " type: " + x.getClass().getCanonicalName()); // invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; // assertEquals(x, java.util.Arrays.asList("one","two")); // mt is (Object,Object,Object)Object mt = MethodType.genericMethodType(3); mh = mh.asType(mt); x = mh.invokeExact((Object) 1, (Object) 2, (Object) 3); // invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; // 1,2,3 System.out.println("x: " + x + " type: " + x.getClass().getCanonicalName()); // assertEquals(x, java.util.Arrays.asList(1,2,3)); // mt is ()int mt = MethodType.methodType(int.class); mh = lookup.findVirtual(java.util.List.class, "size", mt); i = (int) mh.invokeExact(java.util.Arrays.asList(1, 2, 3)); // invokeExact(Ljava/util/List;)I assert (i == 3); mt = MethodType.methodType(void.class, String.class); mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt); mh.invokeExact(System.out, "Hello, world."); // invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V }