@SuppressWarnings("UnusedDeclaration") public static CallSite bootstrapInit(MethodHandles.Lookup caller, String name, MethodType type) { RoboCallSite site = new RoboCallSite(type, caller.lookupClass()); bindInitCallSite(site); return site; }
@SuppressWarnings("UnusedDeclaration") public static CallSite bootstrapStatic( MethodHandles.Lookup caller, String name, MethodType type, MethodHandle original) throws IllegalAccessException { MethodCallSite site = new MethodCallSite(type, caller.lookupClass(), name, original, STATIC); bindCallSite(site); return site; }
public static CallSite bootstrap( MethodHandles.Lookup caller, String name, MethodType type, String targetType) throws NoSuchMethodException, IllegalAccessException, ClassNotFoundException { // lookup the target type within the ClassLoader of the // calling class, otherwise this bootstrap class may not // have visibility (if loaded through AnonymousClassLoader, etc) Class<?> targetClass = Class.forName(targetType, true, caller.lookupClass().getClassLoader()); InterfaceCallSite ics = new InterfaceCallSite(targetClass, name, type); // set the interface class, method name, and method type // as the first arguments of the handle, then have // it collect whatever arguments are sent at runtime // into a trailing Object[] ics.rootHandle = MethodHandles.insertArguments(callHandle, 0, ics) .asVarargsCollector(Object[].class) .asType(type); ics.setTarget(ics.rootHandle); return ics; }
public static void main(String[] arg) throws Throwable { MethodHandles.Lookup lookup = MethodHandles.lookup(); Class thisClass = lookup.lookupClass(); // (who am I?) MethodType methodType; MethodHandle methodHandle; Employee employee = new Employee(); String name; Field fieldName = null; for (Field field : Employee.class.getDeclaredFields()) { if (field.getName().equals("name")) { fieldName = field; fieldName.setAccessible(true); break; } } // Lookup invoke dynamic methodType = MethodType.methodType(String.class); methodHandle = lookup.findVirtual(Employee.class, "getName", methodType); name = (String) methodHandle.invokeExact(new Employee()); System.out.println("invoke dynamic " + name); // Lookup reflection Method method = Employee.class.getMethod("getName", new Class<?>[] {}); name = (String) method.invoke(new Employee()); System.out.println("reflection " + name); // Lookup Handle Field Direct MethodHandle methodHandleFieldDirect = lookup.unreflectGetter(fieldName); name = (String) methodHandleFieldDirect.invokeExact(new Employee()); System.out.println("method handle for field direct " + name); long start = 0; long end = 0; long times = 10_000; long regularTime; long invokeDynamicTime; long reflectionTime; long count = 0; long invokeDynamicTimeUsingField; long fieldDirect; // warm up for (int index = 0; index < times; index++) { employee.getName(); name = (String) methodHandle.invokeExact(employee); name = (String) method.invoke(employee); name = (String) methodHandleFieldDirect.invokeExact(employee); } // regular method call time start = System.nanoTime(); for (int index = 0; index < times; index++) { name = employee.getName(); count += name.hashCode(); } count = 0; end = System.nanoTime(); regularTime = end - start; System.out.printf("regular method call time = %d\n", regularTime / times); // invoke dynamic method call time start = System.nanoTime(); for (int index = 0; index < times; index++) { name = (String) methodHandle.invokeExact(employee); count += name.hashCode(); } count = 0; end = System.nanoTime(); invokeDynamicTime = end - start; System.out.printf("invoke dynamic method call time = %d\n", invokeDynamicTime / times); // reflection method call time start = System.nanoTime(); for (int index = 0; index < times; index++) { name = (String) method.invoke(employee); count += name.hashCode(); } count = 0; end = System.nanoTime(); reflectionTime = end - start; System.out.printf("reflection method call time = %d\n", reflectionTime / times); // start = System.nanoTime(); for (int index = 0; index < times; index++) { name = (String) methodHandleFieldDirect.invokeExact(employee); count += name.hashCode(); } count = 0; end = System.nanoTime(); invokeDynamicTimeUsingField = end - start; System.out.printf( "field method invoke dynamic call time = %d\n", invokeDynamicTimeUsingField / times); // start = System.nanoTime(); for (int index = 0; index < times; index++) { name = (String) fieldName.get(employee); count += name.hashCode(); } count = 0; end = System.nanoTime(); fieldDirect = end - start; System.out.printf("field method reflection call time = %d\n", fieldDirect / times); }