Java中 MethodHandles.Lookup 怎么受限获取不同类中的 Field 和 Method 句柄

胖明吖_3265

胖明吖_3265

2026-07-20

502人浏览

原创

methodhandles.lookup 的访问权限由创建时的 lookup class 和目标成员访问修饰符共同决定,仅能访问 lookup class 自身或同包的非 private 成员,跨包 private 成员需通过 java 9+ 的 privatelookupin 且目标模块必须 opens 对应包。

java中 methodhandles.lookup 怎么受限获取不同类中的 field 和 method 句柄

MethodHandles.Lookup 是 Java 方法句柄机制的核心入口,它决定了你能“看到”并访问哪些类的成员(Field / Method)。它的访问能力不是无限制的,而是严格受制于**创建时的查找上下文(lookup class)** 和 **目标成员的访问修饰符**。简单说:你用哪个类去查,就受那个类的权限约束;查别人家的成员,得看人家是否“开门”。

Lookup 实例的权限由 lookup class 决定

每个 MethodHandles.Lookup 实例都绑定一个“查找类”(lookup class),通常是调用 MethodHandles.lookup() 的当前类(即隐式声明类)。这个类决定了你能合法访问哪些成员:

  • 只能访问该类自身声明的 public、protected、package-private(默认)、private 成员(只要没被模块系统封锁)
  • 能访问同一包内其他类的 public、protected、package-private 成员
  • 不能直接访问其他包中类的 private 或 package-private 成员(即使反射能绕过,Lookup 不行)
  • 跨模块时,还需满足模块导出(exports)和开放(opens)要求 —— 比如想用 Lookup 获取另一个模块中某类的 private field,目标模块必须 opens package.to.target

获取不同类成员时的典型限制与应对

想用 Lookup 获取其他类的 Field 或 Method 句柄,关键看三件事:目标类是否可访问、目标成员是否可见、当前 Lookup 是否有足够权限。

  • 访问同包非 private 成员:直接用 lookup.findGetter/Setter/StaticSetter/StaticGetter 或 findVirtual/findStatic 即可,无需额外操作
  • 访问其他包的 public 成员:可以,但仅限 public;例如 lookup.findVirtual(String.class, "length", MethodType.methodType(int.class)) 合法
  • 访问其他类的 private 成员:不行 —— 除非你用的是该类自身的 Lookup(即在目标类内部调用 MethodHandles.lookup()),或通过 MethodHandles.privateLookupIn(targetClass, lookup)(Java 9+)申请私有访问权(前提是模块允许 opens)
  • 突破限制的常见误区:试图用 MethodHandles.lookup().in(otherClass) 并不能提升权限,这只改变后续查找的“名义上下文”,不改变原始 Lookup 的权限基础

Java 9+ 的 privateLookupIn 是关键突破口

如果确实需要从外部获取某个类的 private 成员句柄(比如做高性能字段读写),且目标类所在模块已开放对应包(opens com.example.foo),可使用:

Java Maven Code Review
Java Maven Code Review

审查Java Maven项目(ZIP压缩包或GitLab仓库URL),检查代码规范、命名、模块边界、可维护性问题以及重复代码。

下载
Lookup targetLookup = MethodHandles.privateLookupIn(TargetClass.class, callerLookup);

其中 callerLookup 是你当前拥有的、有权限调用 privateLookupIn 的 Lookup(通常是本类的 lookup)。这个操作会返回一个新 Lookup,它拥有对 TargetClass 私有成员的访问权 —— 但仅限于 TargetClass 自身声明的 private 成员,不递归授权其父类或内部类。

  • 失败时抛 IllegalAccessException,常见原因:目标模块未 opens、目标类是 final、目标成员是 native 或不存在
  • 注意:即使成功,也不能用它访问其他类的 private 成员,权限严格限定在指定 targetClass 范围内

Field 和 Method 句柄获取的典型方法对照

不同访问场景对应不同查找方法,选错就会抛异常:

  • 实例字段读取:lookup.findGetter(Owner.class, "fieldName", fieldType)
  • 实例字段写入:lookup.findSetter(Owner.class, "fieldName", fieldType)
  • 静态字段读取:lookup.findStaticGetter(Owner.class, "STATIC_FIELD", fieldType)
  • 实例方法调用:lookup.findVirtual(Owner.class, "methodName", methodType)(非 private)或 targetLookup.findSpecial(...)(private,需 targetLookup)
  • 构造器句柄:lookup.findConstructor(Target.class, methodType)(仅限 public 构造器;private 需 privateLookupIn + findConstructor)

不复杂但容易忽略。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

9957

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7102

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6252

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1084

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

888

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1316

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2609

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

19951

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1175

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习