当前位置: 首页 > 面试题库 >

LambdaMetafactory可以访问其他ClassLoader上的类

通正平
2023-03-14
问题内容

我有这段代码可以正常工作:

Method getterMethod = Person.class.getDeclaredMethod("getName");

MethodHandles.Lookup lookup = MethodHandles.publicLookup();
Class<?> declaringClass = getterMethod.getDeclaringClass();
Class<?> returnType = getterMethod.getReturnType();
CallSite getterSite = LambdaMetafactory.metafactory(lookup,
    "apply",
    MethodType.methodType(Function.class),
    MethodType.methodType(Object.class, Object.class),
    lookup.findVirtual(declaringClass, getterMethod.getName(), MethodType.methodType(returnType)),
    MethodType.methodType(propertyType, declaringClass));

Function getterFunction = (Function) getterSite.getTarget().invokeExact();

但是,如果getterMethod方法是从不同的ClassLoader加载的类中的方法,则它将抛出:

Caused by: java.lang.invoke.LambdaConversionException: Invalid caller: java.lang.Object
    at java.lang.invoke.AbstractValidatingLambdaMetafactory.<init>(AbstractValidatingLambdaMetafactory.java:118)
    at java.lang.invoke.InnerClassLambdaMetafactory.<init>(InnerClassLambdaMetafactory.java:155)
    at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:299)

如何将ClassLoader实例传递给LambdaMetafactory


问题答案:

如此回答所述,查找模式必须包含私有访问才能被接受LambdaMetaFactory。基本上,这意味着调用

指定的类,因为它创建了特定的查找实例,或者查找类具有足够的信任关系,可以将查找对象传递给执行实际调用的代码(例如,在使用invokedynamic指向时隐含到特定的引导方法)。

从Java 9开始,提供了一种privateLookupIn(Class, MethodHandles.Lookup)尝试private获取对另一个类具有访问权限的查找对象的方法。如文档所指定,将根据模块访问规则检查访问,即,必须“允许调用者对目标类进行
深入思考 ”。因此,就模块可访问性而言,仍然需要上述信任的存在。我想,这就是去框架的方法,其中框架管理的代码将向框架开放以支持这种访问。

如果那不可行,那么如果您是类加载器的创建者,则此答案包含一个替代方法。它使用类加载器的API注入一个新类,该类创建查找对象并允许创建者访问它。可以想象有多种变化,包括通过让合成类回调创建者的代码以移交查找对象来确保它的安全,而不是将其存储在每个人都可以阅读的字段中。



 类似资料:
  • 问题内容: 假设我正在构建一个井字游戏(因为它与结构非常相似),我希望结果在弹出窗口中显示,并带有一个新的游戏按钮,并且希望此弹出窗口允许我访问设置(另一个按钮)并对其进行更改,使其始终位于弹出窗口中,然后离开并最终将其关闭并开始新游戏。 我希望我可以保持秩序,因此有一个单独的弹出窗口类,可以在其中构建自定义弹出窗口。 显而易见,我将newgame方法和reset方法作为我的游戏网格类的方法。另一

  • 问题内容: 我最近拾起Java并遇到了问题。我有几个具有不同类的文件,但是我无法弄清楚如何访问文件中声明了其他类之外的其他类的对象。例如: 我不确定如何从其他文件和类本身有效访问其他类的这些对象?我知道我可以使对象静态化,然后通过它们所在的类将它们作为变量进行访问,但这似乎有点违反直觉?我来自面向对象较少的编程背景,因此我仍在尝试了解Java的编程风格。 问题答案: 您可能只想要这样的东西: 希望

  • 我目前尝试使用AWS lambda。lambda函数应该从S3 bucket加载zip文件(>10 MB)。S3桶位于中,而lambda函数位于中。 当我尝试保存lambda函数时,我得到: GetObject时出错。S3错误代码:AuthorizationHeaderMalformed。S3错误消息:授权头格式错误;“US-East-1”区域错误;应为“EU-Central-1” 这真的是问题所

  • 问题内容: 我正在开发一个应用程序,当我从列表中选择一个值(文件)时,应该在另一种形式的jTextPane中打开它。我正在使用两个面板,一个是显示我的列表的mainpanel,另一个是ExcelSheet,当我单击列表值时,mainpanel关闭并显示新表单ExcelSheet,但不显示jTextPane中doc文件的内容。 问题答案: 使用封装,为了显示给定文件更新文本窗格中的代码。您可以从添加

  • 问题内容: 我的班级有一个名为DataStorage的哈希图: 如何在另一个类中访问此HashMap中的数据? 问题答案: 将HashMap创建为实例变量,并提供一种将其访问类API的方法:

  • 问题内容: 我的问题与该线程中对LambdaMetafactory的显式使用密切相关,提供了一些很好的示例来使用LambdaMetafactory访问类的静态方法;但是,我想知道访问现有bean实例的非静态字段的等效代码是什么。似乎很难找到一个例子,我的每一次尝试都以无法正常工作的代码结束。 这是bean代码: 在这里,一个工作单元测试成功访问了静态方法“ getStaticObj()”: 现在,