下面列出了java.lang.invoke.MethodHandles#loop ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
public static void testLoopFac() throws Throwable {
MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc};
MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
assertEquals(Fac.MT_fac, loop.type());
assertEquals(120, loop.invoke(5));
}
@Test
public static void testLoopFacNullInit() throws Throwable {
// null initializer for counter, should initialize to 0
MethodHandle[] counterClause = new MethodHandle[]{null, Fac.MH_inc};
MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
assertEquals(Fac.MT_fac, loop.type());
assertEquals(120, loop.invoke(5));
}
@Test
public static void testLoopNullInit() throws Throwable {
// null initializer for counter, should initialize to 0, one-clause loop
MethodHandle[] counterClause = new MethodHandle[]{null, Loop.MH_inc, Loop.MH_pred, Loop.MH_fin};
MethodHandle loop = MethodHandles.loop(counterClause);
assertEquals(Loop.MT_loop, loop.type());
assertEquals(10, loop.invoke(10));
}
@Test
public static void testLoopVoid1() throws Throwable {
// construct a post-checked loop that only does one iteration and has a void body and void local state
MethodHandle loop = MethodHandles.loop(new MethodHandle[]{Empty.MH_f, Empty.MH_f, Empty.MH_pred, null});
assertEquals(MethodType.methodType(void.class), loop.type());
loop.invoke();
}
@Test
public static void testLoopVoid2() throws Throwable {
// construct a post-checked loop that only does one iteration and has a void body and void local state,
// initialized implicitly from the step type
MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, null});
assertEquals(MethodType.methodType(void.class), loop.type());
loop.invoke();
}
@Test
public static void testLoopVoid3() throws Throwable {
// construct a post-checked loop that only does one iteration and has a void body and void local state,
// and that has a void finalizer
MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, Empty.MH_f});
assertEquals(MethodType.methodType(void.class), loop.type());
loop.invoke();
}
@Test
public static void testLoopFacWithVoidState() throws Throwable {
// like testLoopFac, but with additional void state that outputs a dot
MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc};
MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
MethodHandle[] dotClause = new MethodHandle[]{null, Fac.MH_dot};
MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause, dotClause);
assertEquals(Fac.MT_fac, loop.type());
assertEquals(120, loop.invoke(5));
}
@Test
public static void testLoopVoidInt() throws Throwable {
// construct a post-checked loop that only does one iteration and has a void body and void local state,
// and that returns a constant
MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, Empty.MH_c});
assertEquals(MethodType.methodType(int.class), loop.type());
assertEquals(23, loop.invoke());
}
@Test
public static void testLoopWithVirtuals() throws Throwable {
// construct a loop (to calculate factorial) that uses a mix of static and virtual methods
MethodHandle[] counterClause = new MethodHandle[]{null, LoopWithVirtuals.permute(LoopWithVirtuals.MH_inc)};
MethodHandle[] accumulatorClause = new MethodHandle[]{
// init function must indicate the loop arguments (there is no other means to determine them)
MethodHandles.dropArguments(LoopWithVirtuals.MH_one, 0, LoopWithVirtuals.class),
LoopWithVirtuals.permute(LoopWithVirtuals.MH_mult),
LoopWithVirtuals.permute(LoopWithVirtuals.MH_pred),
LoopWithVirtuals.permute(LoopWithVirtuals.MH_fin)
};
MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
assertEquals(LoopWithVirtuals.MT_loop, loop.type());
assertEquals(120, loop.invoke(new LoopWithVirtuals(), 5));
}
@Test
public static void testLoopOmitPred() throws Throwable {
// construct a loop to calculate factorial that omits a predicate
MethodHandle[] counterClause = new MethodHandle[]{null, Fac.MH_inc, null, Fac.MH_fin};
MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
assertEquals(Fac.MT_fac, loop.type());
assertEquals(120, loop.invoke(5));
}
static void testLongSignature(int loopArgs, boolean excessive, boolean run) {
int nClauses = ARG_LIMIT - loopArgs + (excessive ? 1 : 0);
System.out.print((excessive ? "(EXCESSIVE)" : "(LONG )") + " arguments: " + loopArgs + ", clauses: " + nClauses + " -> ");
// extend init to denote what arguments the loop should accept
Class<?>[] argTypes = new Class<?>[loopArgs];
Arrays.fill(argTypes, int.class);
MethodHandle init = MethodHandles.dropArguments(INIT, 0, argTypes);
// build clauses
MethodHandle[][] clauses = new MethodHandle[nClauses][];
MethodHandle[] clause = {init, STEP, PRED_T, FINI};
MethodHandle[] fclause = {init, STEP, PRED_F, FINI};
Arrays.fill(clauses, clause);
clauses[nClauses - 1] = fclause; // make the last clause terminate the loop
try {
MethodHandle loop = MethodHandles.loop(clauses);
if (excessive) {
throw new AssertionError("loop construction should have failed");
} else if (run) {
int r;
if (loopArgs == 0) {
r = (int) loop.invoke();
} else {
Object[] args = new Object[loopArgs];
Arrays.fill(args, 0);
r = (int) loop.invokeWithArguments(args);
}
System.out.println("SUCCEEDED (OK) -> " + r);
} else {
System.out.println("SUCCEEDED (OK)");
}
} catch (IllegalArgumentException iae) {
if (excessive) {
System.out.println("FAILED (OK)");
} else {
iae.printStackTrace(System.out);
throw new AssertionError("loop construction should not have failed (see above)");
}
} catch (Throwable t) {
t.printStackTrace(System.out);
throw new AssertionError("unexpected failure (see above)");
}
}