你的位置:首页 > Java教程

[Java教程]【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.java13  * 14  * @author Administrator15  *16 */17 public class MethodHandleTest18 {19   static class ClassA20   {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 Throwable42   {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, IllegalAccessException52   {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 Throwable59   {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.java13  * 14  * @author Administrator15  *16 */17 public class MethodHandleTest18 {19   static class ClassA20   {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 Throwable60   {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, IllegalAccessException70   {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 Throwable78   {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类型的话,那么就会报错,提示找不到相应的方法

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

 

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

如有知道,还望告知。