Java 8使用lambda访问私有成员?
给出私有成员访问的答案,同时给出基于lambda的成员访问的答案。然而,通过将两者结合起来,我仍然无法找到通过lambda访问私人成员的方法。错误:Java 8使用lambda访问私有成员?,java,lambda,java-8,Java,Lambda,Java 8,给出私有成员访问的答案,同时给出基于lambda的成员访问的答案。然而,通过将两者结合起来,我仍然无法找到通过lambda访问私人成员的方法。错误: Caused by: java.lang.IllegalAccessException: member is private: XXX from ZZZ at java.lang.invoke.MethodHandles$Lookup.revealDirect(MethodHandles.java:1353) at java.lang.invoke
Caused by: java.lang.IllegalAccessException: member is private: XXX from ZZZ
at java.lang.invoke.MethodHandles$Lookup.revealDirect(MethodHandles.java:1353)
at java.lang.invoke.AbstractValidatingLambdaMetafactory.<init>(AbstractValidatingLambdaMetafactory.java:131)
at java.lang.invoke.InnerClassLambdaMetafactory.<init>(InnerClassLambdaMetafactory.java:155)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:299)
原因:java.lang.IllegalAccessException:成员是私有的:来自ZZZ的XXX
在java.lang.invoke.MethodHandles$Lookup.RevelDirect(MethodHandles.java:1353)中
位于java.lang.invoke.AbstractValidatingLambdaMetafactory。(AbstractValidatingLambdaMetafactory.java:131)
位于java.lang.invoke.InnerClassLambdaMetafactory。(InnerClassLambdaMetafactory.java:155)
位于java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:299)
是调用站点生成器的一部分的点。如何自定义生成器以控制其访问检查
更新:per的示例关键部分是
查找
对象,该对象被传递到LambdaMetafactory
,然后在其上调用revealDirect
从:
执行安全和访问检查以确保此查找对象能够再现目标方法句柄。这意味着,如果目标是直接方法句柄,但由不相关的查找对象创建,则破解可能失败
因此,lambda表达式只能访问包含lambda表达式的类可访问的方法,因为JVM提供的Lookup
对象将准确反映这些访问权限
这也适用于JavaBean方法,因为按照惯例,这些方法是public
因此,如果要调用
private
方法,有三个选项:
- 从具有访问权限的
方法的声明类中生成lambda实例。当这个类调用时,它将得到一个适当的private
实例 类还可以创建具有所需功能的查找
查找
实例,并将其移交给另一个(受信任的)类,该类可以使用它执行此类反射操作。这正是执行
指令时隐式发生的情况。包含invokedynamic
指令的类指向invokedynamic
中的引导方法,意味着这种信任 因此,使用所有普通操作,它始终是具有访问权限的类,该类必须启用对另一个类的访问LambdaMetaFactory
- 从Java9开始,使用获取对指定目标类具有私有访问权限的方法句柄。这是根据模块访问规则检查的。对于同一模块内的访问,这应该总是成功的
- 使用更多的黑魔法来获得适当的
实例。您链接的问题提到了非公开的查找。如果您得到这个实例并调用它,您将得到一个具有所需属性的实例。或者,您可以通过查找
创建受限查找对象,并覆盖其访问修饰符(由报告的修饰符)以启用完全访问。显然,这两种方法都需要对不属于.in(declaringClass)
Java API的字段进行访问覆盖公共