7.6.2 Java9增加的VarHandle

7.6.2 Java9增加的VarHandle

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

程序示例

下面程序示范了VarHandle的用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.lang.invoke.*;
import java.util.Arrays;

class User
{
String name;
static int MAX_AGE;
}
public class VarHandleTest
{
public static void main(String[] args)throws Throwable
{
String[] sa = new String[]{"Java", "Kotlin", "Go"};
// 获取一个String[]数组的VarHandle对象
VarHandle avh = MethodHandles.arrayElementVarHandle(String[].class);
// 比较并设置:如果第三个元素是Go,则该元素被设为Lua
boolean r = avh.compareAndSet(sa, 2, "Go", "Lua");
// 输出比较结果
System.out.println(r); // 输出true
// 看到第三个元素被替换成Lua
System.out.println(Arrays.toString(sa));
// 获取sa数组的第二个元素
System.out.println(avh.get(sa, 1)); // 输出Kotlin
// 获取并设置:返回第三个元素,并将第三个元素设为Swift
System.out.println(avh.getAndSet(sa, 2, "Swift"));
// 看到第三个元素被替换成Swift
System.out.println(Arrays.toString(sa));

// 用findVarHandle方法获取User类中名为name,
// 类型为String的实例变量
VarHandle vh1 = MethodHandles.lookup().findVarHandle(User.class,
"name", String.class);
User user = new User();
// 通过VarHandle获取实例变量的值,需要传入对象作为调用者
System.out.println(vh1.get(user)); // 输出null
// 通过VarHandle设置指定实例变量的值
vh1.set(user, "孙悟空");
// 输出user的name实例变量的值
System.out.println(user.name); // 输出孙悟空
// 用findVarHandle方法获取User类中名为MAX_AGE,
// 类型为Integer的类变量
VarHandle vh2 = MethodHandles.lookup().findStaticVarHandle(User.class,
"MAX_AGE", int.class);
// 通过VarHandle获取指定类变量的值
System.out.println(vh2.get()); // 输出0
// 通过VarHandle设置指定类变量的值
vh2.set(100);
// 输出User的MAX_AGE类变量
System.out.println(User.MAX_AGE); // 输出100
}
}

程序调用MethodHandles类的静态方法可获取操作数组的VarHandle对象,接下来程序可通过VarHandle对象来操作数组的方法,包括比较并设置数组元素、获取并设置数组元素等
VarHandle既可设置实例变量的值,也可获取实例变量的值。
使用VarHandle操作类变量与操作实例变量差别不大,区别只是类变量不需要对象,因此使用VarHandle操作类变量时无须传入对象作为参数。
VarHandleMethodHandle一样,它也是一种动态调用机制,当程序通过Methodhandles.Lookup来获取成员变量时,可根据字符串名称来获取成员变量,这个字符串名称同样可以是动态改变的,因此非常灵活。