1. methodHandle 调用
在过去,我们调用一个类的方法,除了直接调用,再就是使用反射来调用了。而今天我要说说 jdk 新引入的方式来调用。
比如我们有一个很简单的 UserService 类。
1
2
3
4
5
6
7
| public class UserService {
public String getUsername(String id) {
return "username" + id;
}
}
|
直接调用和反射调用的方式比较简单,我就不说明了。
下面来演示 invoke
包的使用。
- 使用
MethodHandles.lookup()
来查找对应的方法 - 使用
methodHandle
来调用,分为几种不同的方式
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
| public class UserServiceTest {
private MethodType methodType;
private Lookup lookup;
private MethodHandle methodHandle;
@SneakyThrows
@BeforeEach
public void beforeEach() {
methodType = MethodType.methodType(String.class, String.class);
lookup = MethodHandles.lookup();
methodHandle = lookup.findVirtual(UserService.class, "getUsername", methodType);
}
@SneakyThrows
@Test
public void invokeWithArguments() {
UserService userService = new UserService();
Object obj = methodHandle.bindTo(userService).invokeWithArguments("1");
assertEquals("username1", obj);
}
@SneakyThrows
@Test
public void invoke() {
UserService userService = new UserService();
Object obj = methodHandle.invoke(userService, "1");
assertEquals("username1", obj);
}
/**
* 要求类型全匹配, 包括返回值类型
*/
@SneakyThrows
@Test
public void invokeExact() {
UserService userService = new UserService();
String s = (String) methodHandle.invokeExact(userService, "1");
assertEquals("username1", s);
}
}
|
2. 代码实现位置
github 地址