6.6 变量处理和方法处理

时间:2020-04-07
本文章向大家介绍6.6 变量处理和方法处理,主要包括6.6 变量处理和方法处理使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、Java 9增强的MethodHandle类

MethodHandle为Java增加了方法引用功能,方法引用概念有点类似于C的“函数指针”。这种方法引用是一种轻量级的引用方式,他不会检查方法的访问权限,也不管方法所属的类、实例方法、静态方法,MethodHandle就是简单代表特定的方法,并通过MethodHandle来调用方法。

使用MethodHandle类还涉及几个类:

1、MethodHandles:MethodHandle的工厂类,它提供一些列的静态方法来获取MethodHandle。

2、MethodHandles.Lookup:Lookup静态类也是MethodHandle、VarHandle的工厂类,专门用于获取MethodHandle、VarHandle。

3、MethodType:代表一个方法的类型。MethodType根据方法的形参、返回值类型来确定方法类型。

下面示范MethodHandle的用法

 1 import java.lang.invoke.*;
 2 public class MethodHandleTest
 3 {
 4     // 定义一个private的类方法
 5     private static void hello()
 6     {
 7         System.out.println("Hello world!");
 8     }
 9     // 定义一个private的实例方法
10     private String hello(String name)
11     {
12         System.out.println("执行带参数的hello" + name);
13         return name + ",您好";
14     }
15     public static void main(String[] args) throws Throwable
16     {
17         //引用静态方法名
18         // 定义一个返回值为void、不带形参的方法类型
19         var type = MethodType.methodType(void.class);
20         // 使用MethodHandles.Lookup的findStatic获取类方法
21         var mtd = MethodHandles.lookup()
22             .findStatic(MethodHandleTest.class, "hello", type);
23         // 通过MethodHandle执行方法
24         mtd.invoke();
25 
26         // 使用MethodHandles.Lookup的findVirtual获取实例方法
27         var mtd2 = MethodHandles.lookup()
28             .findVirtual(MethodHandleTest.class, "hello",
29             // 指定获取返回值为String, 形参为String的方法类型
30             MethodType.methodType(String.class, String.class));
31         // 通过MethodHandle执行方法,传入主调对象和参数
32         System.out.println(mtd2.invoke(new MethodHandleTest(), "孙悟空"));
33     }
34 }

执行结果:

1 ---------- 运行Java捕获输出窗 ----------
2 Hello world!
3 执行带参数的hello孙悟空
4 孙悟空,您好
5 
6 输出完成 (耗时 0 秒) - 正常终止 

二、Java 9增加的VarHandle

VarHandle主要用于动态操作数组的元素和对象的成员变量。VarHanbdle和MedthodHandle非常相似,他也需要MethodHandles来获取实例,接下来调用VarHandle的方法即可动态操作数组的元素和指定对象的成员变量。

 1 import java.lang.invoke.*;
 2 import java.util.Arrays;
 3 class User
 4 {
 5     String name;
 6     static int MAX_AGE;
 7 }
 8 public class VarHandleTest
 9 {
10     public static void main(String[] args) throws Throwable
11     {
12         var sa = new String[] {"Java", "Kotlin", "Go"};
13         // 获取一个String[]数组的VarHandle对象
14         var avh = MethodHandles.arrayElementVarHandle(String[].class);
15         // 比较并设置:如果第三个元素是Go,则该元素被设为Lua
16         var r = avh.compareAndSet(sa, 2, "Go", "Lua");
17         // 输出比较结果
18         System.out.println(r); // 输出true
19         // 看到第三个元素被替换成Lua
20         System.out.println(Arrays.toString(sa));
21         // 获取sa数组的第二个元素
22         System.out.println(avh.get(sa, 1)); // 输出Kotlin
23         // 获取并设置:返回第三个元素,并将第三个元素设为Swift
24         System.out.println(avh.getAndSet(sa, 2, "Swift"));
25         // 看到第三个元素被替换成Swift
26         System.out.println(Arrays.toString(sa));
27 
28         // 用findVarHandle方法获取User类中名为name,
29         // 类型为String的实例变量
30         var vh1 = MethodHandles.lookup().findVarHandle(User.class,
31             "name", String.class);
32         var user = new User();
33         // 通过VarHandle获取实例变量的值,需要传入对象作为调用者
34         System.out.println(vh1.get(user)); // 输出null
35         // 通过VarHandle设置指定实例变量的值
36         vh1.set(user, "孙悟空");
37         // 输出user的name实例变量的值
38         System.out.println(user.name); // 输出孙悟空
39         // 用findVarHandle方法获取User类中名为MAX_AGE,
40         // 类型为Integer的类变量
41         var vh2 = MethodHandles.lookup().findStaticVarHandle(User.class,
42             "MAX_AGE", int.class);
43         // 通过VarHandle获取指定类变量的值
44         System.out.println(vh2.get()); // 输出0
45         // 通过VarHandle设置指定类变量的值
46         vh2.set(100);
47         // 输出User的MAX_AGE类变量
48         System.out.println(User.MAX_AGE); // 输出100
49     }
50 }

 从上面前两行的粗体代码可以看出,程序调用MethodHandles类的静态方法来获取操作数组的VarHandle对象,接下来程序可通过VarHandle对象来操作数组的方法,包括设置数组元素、获取并设置数组元素等,VarHandle的及具体方法参看API文档。

后面粗体代码示范了操作实例变量的情形,由于实例变量需要使用对象来访问,因此使用VarHandle操作实例变量时需要传入一个User对象。VarHandle既可以设置实例变量的值,也可以获取实例变量的值。

原文地址:https://www.cnblogs.com/weststar/p/12485721.html