Java 8访问lambda的私有成员? [英] Java 8 access private member with lambda?

查看:126
本文介绍了Java 8访问lambda的私有成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用java.lang.invoke.MethodHandle调用私有方法给出了私有成员访问的答案,而使用LambdaMetafactory的Java访问bean方法给出基于lambda的成员访问的答案。但是,通过组合这两者,我仍然找不到通过lambda访问私有成员的方法。错误:

Invoke private method with java.lang.invoke.MethodHandle gives an answer to private member access, while Java access bean methods with LambdaMetafactory gives an answer to lambda based member access. However, by combining the two, I still can not find a way to access private members via lambda. The error:

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)

指向 revealDirect ,它是 metafactory 调用网站构建器。如何自定义构建器以控制其访问检查?

points to revealDirect which is part of metafactory call site builder. How can I customize the builder to control its access checks?

更新工作解决方案选项#3 Holger

推荐答案

关键部分是传递给 Lookup 的对象 LambdaMetafactory 然后调用 revealDirect

The critical part is the Lookup object that is passed to the LambdaMetafactory on which then revealDirect is invoked.

来自 documententation


执行安全性和访问检查以确保此查找对象能够再现目标方法句柄。这意味着如果target是直接方法句柄但是由不相关的查找对象创建,则破解可能会失败。

Security and access checks are performed to ensure that this lookup object is capable of reproducing the target method handle. This means that the cracking may fail if target is a direct method handle but was created by an unrelated lookup object.

因此, lambda表达式只能访问包含lambda表达式的类可访问的方法,因为提供的JVM Lookup 对象将完全反映这些访问权限。

As a consequence, lambda expression can only access methods accessible by the class containing the lambda expression as the JVM provided Lookup object will reflect exactly these access permissions.

这也适用于Java Beans方法,因为它们按照惯例是 public

This also works for Java Beans methods as these are public by convention.

因此,如果您想调用私有方法,您有三种选择:

So if you want to invoke private methods you have three options:


  • 从有权访问它的 private 方法的声明类中生成lambda实例。当这个类调用 MethodHandles.lookup() 它将获得适当的查找实例

  • Generate the lambda instance from within the declaring class of the private method which has access to it. When this class calls MethodHandles.lookup() it will get an appropriate Lookup instance

类也可以创建具有所需功能的 Lookup 实例,并将其移交给另一个(可信)类,该类可以使用它来执行此类反射操作。这正是在执行 invokedynamic 指令时隐式发生的情况。包含指向 LambdaMetaFactory 中的引导方法的 invokedynamic 指令的类意味着这种信任。

A class may also create such a Lookup instance with the desired capabilities and hand it over to another (trusted) class which may use it to perform such reflective operations. This is exactly what happens implicitly when an invokedynamic instruction is executed. A class containing invokedynamic instructions pointing to a bootstrap method within LambdaMetaFactory implies such trust.

因此,使用所有普通操作,它始终是具有访问权限的类,必须启用对另一个类的访问

So using all-ordinary operations, its always the class having the access permissions which has to enable the access for another class

这篇关于Java 8访问lambda的私有成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆