/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package invokecustom; import java.lang.invoke.CallSite; import java.lang.invoke.ConstantCallSite; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; abstract class Super { public void targetMethodTest4() { System.out.println("targetMethodTest4 from Super"); } public abstract void helperMethodTest9(); } public class InvokeCustom extends Super implements Runnable { public InvokeCustom() {} public InvokeCustom(int i) { System.out.println("InvokeCustom.(" + i + ")"); } private static void targetMethodTest1() { System.out.println("Hello World!"); } private static void targetMethodTest2(boolean z, byte b, char c, short s, int i, float f, long l, double d, String str) { System.out.println(z); System.out.println(b); System.out.println(c); System.out.println(s); System.out.println(i); System.out.println(f); System.out.println(l); System.out.println(d); System.out.println(str); } private static void targetMethodTest3() { System.out.println("targetMethodTest3 from InvokeCustom"); } @Override public void targetMethodTest4() { // The generated code should be calling Super.targetMethodTest4. System.out.println("targetMethodTest4 from InvokeCustom (oops!)"); } public static int targetMethodTest5(int x, int y, int total) { int calculated = x + y; System.out.println("targetMethodTest5 " + x + " + " + y + " = " + calculated); if (calculated != total) { System.out.println("Failed " + calculated + " != " + total); } return calculated; } public static long targetMethodTest6(long x, long y, long total) { long calculated = x + y; System.out.println("targetMethodTest6 " + x + " + " + y + " = " + calculated); if (calculated != total) { System.out.println("Failed " + calculated + " != " + total); } return calculated; } public static double targetMethodTest7(float x, float y, double product) { double calculated = x * y; System.out.println("targetMethodTest7 " + x + " * " + y + " = " + calculated); if (calculated != product) { System.out.println("Failed " + calculated + " != " + product); } return calculated; } public static void targetMethodTest8(String s) { System.out.println("targetMethodTest8 " + s); } private static int staticFieldTest9 = 0; private static void checkStaticFieldTest9(MethodHandle getter, MethodHandle setter) throws Throwable { final int NEW_VALUE = 0x76543210; int oldValue = (int) getter.invokeExact(); setter.invokeExact(NEW_VALUE); int newValue = (int) getter.invokeExact(); System.out.print("checkStaticFieldTest9: old " + oldValue + " new " + newValue + " expected " + NEW_VALUE + " "); System.out.println((newValue == NEW_VALUE) ? "OK" : "ERROR"); } private float fieldTest9 = 0.0f; private void checkFieldTest9(MethodHandle getter, MethodHandle setter) throws Throwable { final float NEW_VALUE = 1.99e-19f; float oldValue = (float) getter.invokeExact(this); setter.invokeExact(this, NEW_VALUE); float newValue = (float) getter.invokeExact(this); System.out.print("checkFieldTest9: old " + oldValue + " new " + newValue + " expected " + NEW_VALUE + " "); System.out.println((newValue == NEW_VALUE) ? "OK" : "ERROR"); } public void helperMethodTest9() { System.out.println("helperMethodTest9 in " + InvokeCustom.class); } private static void targetMethodTest9() { System.out.println("targetMethodTest9()"); } public void run() { System.out.println("run() for Test9"); } public static CallSite bsmLookupStatic(MethodHandles.Lookup caller, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { System.out.println("bsmLookupStatic []"); final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type); return new ConstantCallSite(targetMH.asType(type)); } public static CallSite bsmLookupStaticWithExtraArgs( MethodHandles.Lookup caller, String name, MethodType type, int i, long l, float f, double d) throws NoSuchMethodException, IllegalAccessException { System.out.println("bsmLookupStaticWithExtraArgs [" + i + ", " + l + ", " + f + ", " + d + "]"); final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type); return new ConstantCallSite(targetMH.asType(type)); } public static CallSite bsmCreateCallSite( MethodHandles.Lookup caller, String name, MethodType type, MethodHandle mh) throws Throwable { System.out.println("bsmCreateCallSite [" + mh + "]"); return new ConstantCallSite(mh); } private void privateMethodTest9() { System.out.println("InvokeCustom.privateMethodTest9()"); } public static CallSite bsmLookupTest9(MethodHandles.Lookup caller, String name, MethodType type, MethodHandle staticGetter, MethodHandle staticSetter, MethodHandle fieldGetter, MethodHandle fieldSetter, MethodHandle instanceInvoke, MethodHandle constructor, MethodHandle interfaceInvoke, MethodHandle privateInvoke) throws Throwable { System.out.println("bsmLookupTest9 [" + staticGetter + ", " + staticSetter + ", " + fieldGetter + ", " + fieldSetter + "]"); System.out.println(name + " " + type); // Check constant method handles passed can be invoked. checkStaticFieldTest9(staticGetter, staticSetter); InvokeCustom instance = new InvokeCustom(); instance.checkFieldTest9(fieldGetter, fieldSetter); // Check virtual method. instanceInvoke.invokeExact(instance); InvokeCustom instance2 = (InvokeCustom) constructor.invokeExact(3); interfaceInvoke.invoke(instance2); privateInvoke.invoke(instance2); final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type); return new ConstantCallSite(targetMH.asType(type)); } public static void lambdaTest() { List strings = Arrays.asList(new String[] { "Three", "One", "FortyTwo" }); String sample = strings.stream().filter(x -> "One".equals(x.trim())) .map(String::trim).findAny().orElse(""); strings.stream().forEach(System.out::println); } }