gpt4 book ai didi

Java 8 使用 lambda 访问私有(private)成员?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:17:42 25 4
gpt4 key购买 nike

Invoke private method with java.lang.invoke.MethodHandle给出私有(private)成员访问的答案,而Java access bean methods with LambdaMetafactory给出了基于 lambda 的成员访问的答案。但是,通过结合两者,我仍然找不到通过 lambda 访问私有(private)成员的方法。错误:

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 的一部分调用网站 build 者。如何自定义构建器以控制其访问检查?

更新:Working Solution Option #3 的示例每Holger

最佳答案

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

来自documententation :

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对象将准确反射(reflect)这些访问权限。

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


所以如果你想调用 private方法你有三个选择:

  • private 的声明类中生成 lambda 实例可以访问它的方法。当这个类调用 MethodHandles.lookup() 它会得到一个合适的 Lookup实例

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

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

  • 从 Java 9 开始,使用 MethodHandles.privateLookupIn(Class, MethodHandles.Lookup) 获取对指定目标类具有私有(private)访问权限的方法句柄。这是根据模块访问规则检查的。对于同一模块内的访问,这应该始终成功。
  • 使用更多黑魔法获得合适的 Lookup实例。您链接的问题提到了非 public Lookup.IMPL_LOOKUP .如果你接触到这个实例并调用 in(declaringClass) 在它上面,你会得到一个具有所需属性的实例。或者,您可以通过 MethodHandles.publicLookup() 创建一个受限制的查找对象.in(declaringClass)并覆盖其访问修饰符(由 lookupModes() 报告的修饰符以启用完全访问权限。显然,两者都需要对不属于 public Java API 的字段进行访问覆盖。

关于Java 8 使用 lambda 访问私有(private)成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28184065/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com