问题标签 [methodhandle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
97 浏览

java - Java 方法句柄;在多个位置使用参数

在 Java 中,我可以将多个方法句柄与每个参数结合起来,如下所示:

..通过使用MethodHandles.collectArguments()

我得到的方法句柄可以这样调用:

但是现在,我想获得一个方法句柄,它将其参数分派到调用树中,如下所示:

我无法解决如何做到这一点。你能帮助我吗?

0 投票
1 回答
83 浏览

java - MethodHandles.filterArguments() 示例给出异常

使用 Java 1.8.0_92,尝试运行 MethodHandles 的示例。filterArguments(),抛出以下异常:

代码是:

知道有什么问题吗?

0 投票
1 回答
576 浏览

java - 插入后如何更改 MethodHandle 参数?

假设你MethodHandle已经指定了一些参数,设置后如何更改这些参数?

我曾尝试使用 MethodHandles。过滤器参数()

但我得到一个例外:

0 投票
1 回答
1130 浏览

java - MethodHandles 还是 LambdaMetafactory?

在我的工作中,我们有一个用于指定数学公式的 DSL,我们后来将其应用于很多点(以百万计)。

截至今天,我们构建了公式的 AST,并访问每个节点以生成我们所谓的“评估器”。然后我们将公式的参数传递给该评估器,并针对每个点进行计算。

例如,我们有这个公式:x * (3 + y)

我们的评估器将为每个步骤发出“评估”对象。

这种方法易于编程,但效率不高。

所以我开始研究方法句柄来建立一个“组合”的方法句柄来加快速度。

沿着这个:我有我的“算术”课:

在构建我的 AST 时,我使用 MethodHandles.lookup() 直接获取这些句柄并组合它们。沿着这些思路,但在一棵树上:

可悲的是,我对结果感到非常失望。例如,方法句柄的实际构造非常长(由于调用 MethodHandles::insertArguments 和其他此类组合函数),并且为评估增加的加速仅在超过 600k 次迭代后才开始产生影响。

在 1000 万次迭代时,方法句柄开始真正发光,但数百万次迭代还不是(还?)一个典型的用例。我们更多的是在 10k-1M 左右,结果好坏参半。

此外,实际计算速度加快了,但速度不快(约 2-10 倍)。我期待这东西跑得快一点..

所以无论如何,我再次开始搜索 StackOverflow,并看到了像这样的 LambdaMetafactory 线程:https ://stackoverflow.com/a/19563000/389405

我很想开始尝试这个。但在此之前,我希望您能就一些问题提供意见:

  • 我需要能够编写所有这些 lambda。MethodHandles 提供了很多(不可否认的缓慢)方法来做到这一点,但我觉得 lambdas 有一个更严格的“接口”,我还不能解决如何做到这一点。你知不知道怎么?

  • lambdas 和方法句柄是相互关联的,我不确定我是否会获得显着的加速。我看到了简单 lambda 的这些结果:direct: 0,02s, lambda: 0,02s, mh: 0,35s, reflection: 0,40但是组合 lambda 呢?

多谢你们!

0 投票
1 回答
229 浏览

java - 池捕获 lambda

我认为为了捕获 lambda,需要分配一个对象(无论是它Object[]还是某种abc$Lambda$xyz类型)。无论如何都可以自定义此过程吗?假设我有这个代码:

而且我不想分配对象捕获x,而是从池中获取它并填写值;我也知道在某些时候我可以将对象返回到池中。

我可以写

并且我可以为不同的参数类型提供专门的版本(因为 usingObject...会进行分配(好吧,分配可能会被转义分析消除......)但这会使代码变得非常不可读。因此我正在寻找一种更像方面的方式。

这样的事情可能吗?


编辑:为了使池的功能更加明显,get可以实现为

对于我想使用的所有可能类型的 lambda,我需要这种具有特定签名的持有者。

也许我通过提供函数使示例变得有点复杂 - 但我想捕捉这样一个事实,即在Supplier.get()调用时可能会对捕获的参数应用额外的计算。

请忽略 int 被装箱的事实,它可以产生分配。

0 投票
5 回答
1308 浏览

java - 使用 MethodHandle 查找最具体的重载方法

假设我在给定类型(类/接口)中有三个方法:

使用 aMethodHandle或反射,我想为仅在运行时知道类型的对象找到最具体的重载方法。即我想在运行时执行JLS 15.12

例如,假设我在包含这三种方法的上述类型的方法中有以下内容:

然后我在概念上会希望foo(Number number)被选中,但上面会抛出异常,因为 API 只会查找foo(Long)方法而不会查找其他内容。请注意,Long此处的用法仅作为示例。对象的类型实际上可以是任何东西;String, MyBar, Integer, ..., 等等等等。

MethodHandle API 中是否有某些东西可以在运行时自动执行与编译器在 JLS 15.12 之后执行的相同类型的解析?

0 投票
2 回答
3835 浏览

java - 如何删除用作侦听器的 lambda 表达式/方法句柄?

Java 8 引入了lambda 表达式,这是一件很棒的事情。但现在考虑重写这段代码:

使用 lambda 表达式和方法引用,不再需要B实现PropertyChangeListner,因为我们可以编写

我认为新代码不仅更短,而且更简洁,更易于理解。但是在阅读了这里给出的答案之后(这个答案的重复,但我认为问题和答案更清晰),我看不出有什么方法可以实现一个调用的方法stopListening(),它会再次删除听众。

我确信我不是第一个偶然发现这一点的人。那么有没有人找到一个很好的解决方案来解决如何使用本示例中所示的方法句柄,并且以后仍然能够再次删除侦听器?

更新

那很快。基于 Mike Naklis 和 Hovercraft Full Of Eels 的回答,我得出了以下结论:

0 投票
0 回答
1734 浏览

java - java.lang.NoClassDefFoundError:jdk.nashorn.internal.scripts.JO28P0

我完成了一个 Java 库,并用它来替换java.lang.invoke包(即,在正常 JVM 库之前将其添加到引导类加载器)。在包中,它为方法句柄动态生成字节码。如果您有任何关于这门课的信息,谢谢!

目前,这个包在带有测试用例的 JRuby 上运行良好,但是当我尝试用 Nashorn(JavaScript 语言的 Java 版本)测试它时它失败了。错误信息是:

除了例外,我在 nashorn 包中找不到任何类 JO28P0。我无法通过谷歌获得该课程的任何信息。

这里的 JS 来自 octane 基准测试,我在其中评论了除前两种情况之外的所有测试:

启动该案例的主要 Java 代码是:

一个 VM 参数是-Djit_bytecode=true. 如果这个论点是真的,那么将去我的图书馆。否则,我的库将不会生效。

如果jit_bytecode为假,则异常消失。


更新:

我的代码发出动态字节码,其中包含 symbol JO28P0。当我尝试使用UNSAFE.defineAnonymousClass(). 那么如何使用 Structure ClassLoaderUnsafe.defineAnonymousClass才能成功呢?

0 投票
0 回答
477 浏览

java - ScriptEngineManager.getEngineByName("nashorn") 由于 java.lang.invoke.WrongMethodTypeException 而失败

我无法在 Java 8 (IBM J9JVM) 中创建ScriptEnginenashorn在下面的代码中,引擎是null.

这个失败是由我的库引入的,它为java.lang.invoke包中的 MethodHandle 执行字节码生成。我的图书馆的变化是:

  1. 更改仅适用于标准java.lang.invoke包。nashorn 没有任何变化。
  2. 当 nashorn 即将使用 设置调用站点的目标时Methodhandle target,我的库将转换target为另一个方法句柄b,如果从target创建GuardWithTestHandle并将调用站点的目标设置为b。两个“目标andb”具有相同的方法类型。

我的上一个版本库于 2016 年 10 月完成,对 Nashorn 来说还可以。但是我构建的新版本WrongMethodTypeException在执行时有getEngineByName. 此异常在内部处理getEngineByName并返回 null。

我得到的 nashorn 源代码与 JVM 中的 nashorn.jar 不一致。在调试过程中,我发现异常来自:

全局 = createNashornGlobal();

里面NashornScriptEngine.<init>UserAccessorProperty深入消化后,在(line318)处进行MethodHandle调用时抛出异常

在第 318 行,invokerisMutableCallSiteDynamicInvokerHandle及其方法类型为(Object,Object)Objectfunc和都在这里self声明为Object对象,参数类型和返回值完全匹配。

我无法理解此异常,也不知道此问题的后续步骤。谢谢,如果你能在这里为这个问题提供一些想法和建议吗?或一些选项/配置..

见栈堆栈的调试屏幕截图

0 投票
0 回答
143 浏览

java - 在 WAR 文件中使用 MethodHandle.publicLookup() 时出现 LinkageError

我们有一个问题,我们无法解释它为什么会发生。也许这里有人可以给我们一些提示,在这种情况下发生了什么。

我们写了一个简单的reproucer来显示问题

当我们现在构建一个war文件并将其分解到tomcat时一切都很好,但是当我们使用不同的上下文路径第二次部署它时,它会崩溃并出现以下异常

我们唯一发现的原因是publicLookup()。查看 javadoc 在使用 publicLookup() 时提到了一些问题,我们并不完全理解它。