文章目录
- 509. Java 方法句柄 - Lookup 与 MethodType
- 1. Lookup —— 方法句柄的工厂
- 2. MethodType —— 方法签名的描述符
- 3. 查找不同类型的方法
- 🔸 查找实例方法:`findVirtual`
- 🔸 查找静态方法:`findStatic`
- 🔸 查找构造函数:`findConstructor`
- 4. 总结 🎓
509. Java 方法句柄 - Lookup 与 MethodType
在使用Method Handles之前,我们需要明确两个核心要素:
- Lookup 对象:负责查找方法/字段/构造函数。
- MethodType 对象:描述方法的签名(返回值类型 + 参数类型)。
1. Lookup —— 方法句柄的工厂
在创建 Method Handle 时,必须先有一个Lookup 对象。
Lookup 决定了你能访问的范围。
只查找公共成员:
MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();👉 只能访问public 类中的 public 成员。这样更安全,避免意外暴露私有方法。
完全访问(包括 private/protected):
MethodHandles.Lookup lookup = MethodHandles.lookup();👉 适合在类内部或受信任的范围内使用。但注意:如果这种 lookup 暴露出去,私有方法也可能被间接访问。
📌最佳实践:
- 如果 Method Handle 只在类内部使用,可以放心用
lookup()。 - 如果可能被暴露给外部代码,请用
publicLookup(),限制只访问公开 API。
2. MethodType —— 方法签名的描述符
MethodType是方法签名的抽象,描述了:
- 返回值类型(第一个参数)
- 参数类型(后续参数)
示例:一个返回int、接收String参数的方法签名:
MethodType methodType = MethodType.methodType(int.class, String.class);这样我们就能告诉 JVM:
“我要找一个返回 int、接收 String 的方法。”
3. 查找不同类型的方法
Lookup 提供不同的查找方式:
🔸 查找实例方法:findVirtual
比如String.replace(char oldChar, char newChar):
MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType replaceType = MethodType.methodType(String.class, char.class, char.class); MethodHandle replaceHandle = lookup.findVirtual(String.class, "replace", replaceType); String result = (String) replaceHandle.invoke("banana", 'a', 'o'); System.out.println(result); // bonono👉 第一个参数"banana"是调用该实例方法的对象。
🔸 查找静态方法:findStatic
比如String.valueOf(Object obj):
MethodType valueOfType = MethodType.methodType(String.class, Object.class); MethodHandle valueOfHandle = lookup.findStatic(String.class, "valueOf", valueOfType); String result = (String) valueOfHandle.invoke(12345); System.out.println(result); // "12345"🔸 查找构造函数:findConstructor
比如new StringBuilder(String str):
MethodType constructorType = MethodType.methodType(void.class, String.class); MethodHandle constructorHandle = lookup.findConstructor(StringBuilder.class, constructorType); StringBuilder sb = (StringBuilder) constructorHandle.invoke("Hello"); System.out.println(sb.toString()); // Hello4. 总结 🎓
- Lookup 决定访问范围:安全边界要牢记。
- MethodType 是“方法签名描述符”:必须精确匹配返回值和参数类型。
- 三类查找方法:
findVirtual—— 实例方法findStatic—— 静态方法findConstructor—— 构造函数
- 调用方式统一:
methodHandle.invoke(对象, 参数...)
💡 建议在培训时加一个对照表:
| 查找方式 | 示例 | 说明 |
|---|---|---|
findVirtual | String.replace(char, char) | 调用实例方法 |
findStatic | String.valueOf(Object) | 调用静态方法 |
findConstructor | new StringBuilder(String) | 调用构造方法 |