zoukankan      html  css  js  c++  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.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类型的话,那么就会报错,提示找不到相应的方法

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

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

    如有知道,还望告知。

  • 相关阅读:
    【Python】【文件】查找指定路径中是否存在目标文件(含此路径下的子文件夹)
    时隔一年的2020noip
    nacos 笔记
    webflux 小例子
    spring Initializr 笔记
    临时~spring启动过程
    Mac通过crontab设置定时任务报错Operation not permitted
    Isolation Forest Implementation(孤立森林)
    let arr=['a'] JSON.stringify(arr) 输出:“['a']” let arr2 = “['a']” JSON.parse(arr2) 输出: ['a']
    js对象中key值加引号和不加引号的区别
  • 原文地址:https://www.cnblogs.com/cutter-point/p/5394616.html
Copyright © 2011-2022 走看看