【JVM】2、关于jdk7的MethodHandle类

关于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类型的话,那么就会报错,提示找不到相应的方法

而且我们吧两句输出中的上面一个去掉的话那么也会报错!!!!

具体原因是什么还没有得到确切的答案!!!!

如有知道,还望告知。

原文地址:https://www.cnblogs.com/cutter-point/p/5394616.html