And*_*tin 7 java lambda java-8
使用java.lang.invoke.MethodHandle调用私有方法给出了私有成员访问的答案,而使用LambdaMetafactory的Java访问bean方法给出了基于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.AbstractValidatingLambdaMetafactory.<init>(AbstractValidatingLambdaMetafactory.java:131)
at java.lang.invoke.InnerClassLambdaMetafactory.<init>(InnerClassLambdaMetafactory.java:155)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:299)
Run Code Online (Sandbox Code Playgroud)
指向revealDirect,它是metafactory调用站点构建器的一部分.如何自定义构建器以控制其访问检查?
更新:每个Holger 工作解决方案选项#3的示例
关键部分是Lookup传递给LambdaMetafactoryon 的对象,然后revealDirect调用该对象.
从文件记录:
执行安全性和访问检查以确保该查找对象能够再现目标方法句柄.这意味着如果target是直接方法句柄但是由不相关的查找对象创建,则破解可能会失败.
因此,lambda表达式只能访问包含lambda表达式的类可访问的方法,因为JVM提供的Lookup对象将准确反映这些访问权限.
这也适用于Java Beans方法,因为这些是public按照惯例.
因此,如果要调用private方法,则有三个选项:
从private有权访问它的方法的声明类中生成lambda实例.当这个类调用MethodHandles.lookup()它时,它将获得一个适当的Lookup实例
类也可以创建Lookup具有所需功能的这样的实例,并将其交给另一个(可信的)类,该类可以使用它来执行这样的反射操作.这正是invokedynamic执行指令时隐式发生的事情.包含invokedynamic指向其中的引导方法的指令的类LambdaMetaFactory意味着这种信任.
因此,使用所有普通操作,它始终是具有访问权限的类,必须启用对另一个类的访问
MethodHandles.privateLookupIn(Class, MethodHandles.Lookup)获取具有指定目标类的私有访问权限的方法句柄.这是根据模块访问规则进行检查的.对于同一模块内的访问,这应该总是成功.Lookup实例.你联系的问题提到了非public Lookup.IMPL_LOOKUP.如果您开始使用此实例并对其进行调用in(declaringClass),则会获得具有所需属性的实例.或者,您可以通过创建受限查找对象并覆盖其访问修饰符(报告的访问修饰符以启用完全访问权限.显然,两者都需要对不属于Java API的字段进行访问覆盖.MethodHandles.publicLookup() .in(declaringClass)lookupModes()public| 归档时间: |
|
| 查看次数: |
1674 次 |
| 最近记录: |