关于MethodHandle类,这个类是在jdk1.7之后加入的,这个类的作用类似函数指针的意思
这个类中有一个方法
这里我的jdk有一个问题,就是我在进行MethodHandle操作的时候,我们会发现我们的方法只能设定想要的返回值和参数,但是我们相应的方法里面却不能对这些方法进行操作,参数能操作的int类型的会报错,char也会报错
但是double类型不会出错
1 package ch08.MethodHandle; 2 3 import java.lang.invoke.MethodHandle; 4 import java.lang.invoke.MethodType; 5 6 import static java.lang.invoke.MethodHandles.lookup; 7 8 /** 9 * 10 * 功能:测试使用MethodHandleTest这个类 11 * 时间:上午9:49:16 12 * 文件:MethodHandleTest.java 13 * 14 * @author Administrator 15 * 16 */ 17 public class MethodHandleTest 18 { 19 static class ClassA 20 { 21 public void println(String s) 22 { 23 System.out.println(s); 24 } 25 26 public void xixi(char g) 27 { 28 System.out.println("zheli shi gg" + g); 29 30 char a = 'a'; 31 a = g; 32 33 //以下片段加上就会报错!!!! 34 // int a = 1; 35 // a = a + g; 36 //char s = (char) ('a' + g); 37 // return s; 38 } 39 } 40 41 public static void main(String[] args) throws Throwable 42 { 43 Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA(); 44 45 // 这个方法调用的结果是不论实际类型是那种,最终都可以实现对应的操作 46 //getPrintlnMH(obj).invokeExact("aksdjadj"); 47 48 getPrintXixi(obj).invokeExact(3.25); 49 } 50 51 private static MethodHandle getPrintXixi(Object clazz) throws NoSuchMethodException, IllegalAccessException 52 { 53 MethodType mt = MethodType.methodType(void.class, char.class); 54 55 return lookup().findVirtual(clazz.getClass(), "xixi", mt).bindTo(clazz); 56 } 57 58 private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable 59 { 60 // 这个是方法类型,第一个参数是返回类型,第二个参数是我们的参数类型,后面还有可以有其他的类型 61 MethodType mt = MethodType.methodType(void.class, String.class); 62 63 // 这个lookup方法中find是用来查找我们制定的类里面时候含有这个println这个类和相对应的方法类型,然后我们的bindto是返回这个方法的MethodHandle句柄 64 return lookup().findVirtual(reveiver.getClass(), "println", mt).bindTo(reveiver); 65 } 66 }
报错还根据我么执行的次数不同有差异!!!!
我们再看看这个
1 package ch08.MethodHandle; 2 3 import java.lang.invoke.MethodHandle; 4 import java.lang.invoke.MethodType; 5 6 import static java.lang.invoke.MethodHandles.lookup; 7 8 /** 9 * 10 * 功能:测试使用MethodHandleTest这个类 11 * 时间:上午9:49:16 12 * 文件:MethodHandleTest.java 13 * 14 * @author Administrator 15 * 16 */ 17 public class MethodHandleTest 18 { 19 static class ClassA 20 { 21 public void println(String s) 22 { 23 System.out.println(s); 24 } 25 26 public void xixi(char g) 27 { 28 System.out.println("zheli shi gg" + g); 29 30 char a = 'a'; 31 a = g; 32 33 //以下片段加上就会报错!!!! 34 // int a = 1; 35 // a = a + g; 36 //char s = (char) ('a' + g); 37 // return s; 38 } 39 40 public void xixi(double g) 41 { 42 43 double a = 2.565; 44 45 a += g; 46 47 //好吧,如果上面这句没有进程输出的话,那么就会在下一句爆粗,无法输出!!!! 48 System.out.println("zheli shi gg" + g); 49 System.out.println("zheli shi gg" + a); 50 51 //以下片段加上就会报错!!!! 52 // int a = 1; 53 // a = a + g; 54 //char s = (char) ('a' + g); 55 // return s; 56 } 57 } 58 59 public static void main(String[] args) throws Throwable 60 { 61 Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA(); 62 63 // 这个方法调用的结果是不论实际类型是那种,最终都可以实现对应的操作 64 //getPrintlnMH(obj).invokeExact("aksdjadj"); 65 66 getPrintXixi(obj).invokeExact(3.25); 67 } 68 69 private static MethodHandle getPrintXixi(Object clazz) throws NoSuchMethodException, IllegalAccessException 70 { 71 // MethodType mt = MethodType.methodType(void.class, char.class); 72 MethodType mt = MethodType.methodType(void.class, double.class); 73 74 return lookup().findVirtual(clazz.getClass(), "xixi", mt).bindTo(clazz); 75 } 76 77 private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable 78 { 79 // 这个是方法类型,第一个参数是返回类型,第二个参数是我们的参数类型,后面还有可以有其他的类型 80 MethodType mt = MethodType.methodType(void.class, String.class); 81 82 // 这个lookup方法中find是用来查找我们制定的类里面时候含有这个println这个类和相对应的方法类型,然后我们的bindto是返回这个方法的MethodHandle句柄 83 return lookup().findVirtual(reveiver.getClass(), "println", mt).bindTo(reveiver); 84 } 85 }
当我们的类型是double类型的时候
我们得到了相应的输出,如果是int类型的话,那么就会报错,提示找不到相应的方法
而且我们吧两句输出中的上面一个去掉的话那么也会报错!!!!
具体原因是什么还没有得到确切的答案!!!!
如有知道,还望告知。