问题标签 [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.
java - 为什么我不能 .invokeExact() 在这里,即使 MethodType 是好的?
对于我的一个项目,我必须动态调用构造函数。但由于这是 Java 7,而不是“经典”反射 API,我使用 java.lang.invoke。
代码:
好的,这行得通。
我遇到的问题是这条线:
如果我替换invoke
为invokeExact
,我会得到这个堆栈跟踪:
我不太明白。GlobPathMatcher
和都RegexPathMatcher
使用一个带有 aString
作为参数的构造函数,MethodType
因此 for both 是在 中定义的CONSTRUCTOR_TYPE
。如果不是这样,我无论如何都无法“抓住” MethodHandle
s。
然而我得到一个WrongMethodTypeException
. 为什么?
编辑:这是我阅读答案后的代码;现在我不需要中间地图:我只需要一张地图,将 a 映射String
到 a MethodHandle
:
java - BootstrapMethodError caused by LambdaConversionException caused by using MethodHandle::invokeExact as a method reference
I was trying to check if it is possible to use MethodHandle::invoke or MethodHandle::invokeExact as method references for a functional interface that accepts a MethodHandle and returns a generified output.
(I know that invoke and invokeExact are signature polymorphic, hence the metafactory call in InvokeExact. However, I wanted to know if the compiler is able to elide the things that I had to do to derive a suitable version of invoke/invokeExact.)
invoke.InvokeExact0
Result
The good news is that the metafactory approach was able to synthesize a working functional interface instance (as printed: invoke.InvokeExact0$$Lambda$1/1878246837@1be6f5c3). The bad news is that the method reference approach resulted in a LambdaConversionException, which in turn resulted in a BootstrapMethodError.
I would then like to ask how I am supposed to interpret the error details in LambdaConversionException, since the metafactory workaround exists anyway.
java - 用于 Lambda 方法引用的可理解 toString
有没有办法让toString
使用方法句柄生成的 lambda 可以理解?在 Java 8 之前,我一直在使用Function
Guava 的接口,并创建了一个脚本,为我的许多数据类生成函数。我还包括一个toString
清楚地标识它的类和方法,例如,'MyItem::getPrice'。
然而,在 Java 8 中,虽然声明函数变得更加容易,但我现在无法确定函数是什么。nice 最重要的原因toString
是出于调试目的,但我相信还有其他原因。如果这些信息可以通过反射获得,那就太好了,但显然不是。
此代码段
生产
正如你所看到的,甚至没有一些 lambda 超类可以使用。
澄清
我不是在问我如何定义我自己的toString
,而是我如何确定这个 lambda 调用的类/方法。定义我自己的toString
会破坏使用 Java 8 lambdas 的全部目的,因为我需要做更多容易错字的工作才能获得一个像样的toString
. 我还不如只使用没有 lambdas 的自动化脚本。
java - MethodHandle InvokeExact 参数
我对方法句柄的方法参数感到困惑。我先构建一个guardwithtest方法句柄如下图:
对我来说,问题是如何将参数传递给三个方法句柄:test、trueTarget 和 faliover。1、invokeExact的第一个参数“result”作为receiver传递给test guard,第二个参数“data”传递给startWith:
但是这三个参数被传递给 falseTarget 为:
那么,参数传递的规则是什么,它们如何与方法句柄引用的方法匹配?
java - MethodHandle 的 MethodType 转换以接受 Array Object 参数
我想适应String.startsWith
from (String, String)boolean
to (String[])boolean
,以便它可以接受String[]
参数,其中前两个参数将映射到(String, String)
. 因此,我写了下面的示例代码:
MethodHandle
toString.startsWith
适应boolean (String[])
于最初的适应。但结果表明adapt.invokeExact
失败。
堆栈跟踪中的新(String[])
对象非常令人困惑。任何人都可以就如何解决它提供一些建议吗?
谢谢
这个问题可以抽象为:如何适应一个Methodhandle
只接受的(String, String)boolean
,以便它可以接受(String[])boolean
参数?
java - 使用方法句柄转发功能接口上的调用
TL;DR: 我试图找到最有效的方法来动态创建功能接口的实现,该接口将调用转发到该接口的一组实例。
目标是简化接口的实现,允许客户端代码通过将处理程序(实现为功能接口)传递给适当的注册函数来为多个事件注册自己。一个例子:
这可以是这种界面的一个示例。会有很多这样的接口,每个接口都有不同的事件,所以实现应该尽可能简单,没有太多重复的代码。Event
我想通过在这样的实现中引入一种供内部使用的类型,这可能最好地实现,它允许将调用转发到所有注册的处理程序:
的实现TrainStation
可能如下所示:
这是所需代码的可管理级别。它的大部分可以提取到一个抽象类中,因此每个接口只需要一次。当然,任何减少它的方法都是一个加号,但如果不暴露Event
实例,我看不到直接的方法。
继续使用这种方法,有趣的是接口的实现Event
。我当然可以想象用普通的旧反射来做这件事,它的表现可以接受但不是很出色。但我认为,对于 Java 1.7 或 1.8,现在应该有一种更有效和/或更直接的方式来实现Event.getMasterHandler()
使用新 API 的返回值,尤其是MethodHandle
,因为我们知道每个处理程序接口都是一个函数式接口。我该怎么做呢?
java - 对象上的 InvokeExact,其类型由类加载器动态加载
我花了一整天的时间来解决这个问题。我的问题是如何对实例进行 MethodHandle.invokeExact 调用,该实例的类类型在程序运行时动态加载。为了使问题更清楚,我在下面显示我的示例代码:
在这个示例中,expClass 是动态加载的,它的类类型是AddSample
. 下一行中的 obj 实例被声明为 BaseTemplate,其真实类型为AddSample
. AddSample 类是 BaseTemplate 的子类。然后一个 MethodHandle myMh 被创建到 add 函数,AddSample
但 myMH 的调用失败,因为 receiverType 不匹配。
引发myMH.invokeExact
运行时错误
因为 this 的接收者myMH
被声明为在 expClass (AddSample) 上,但是obj
当前提供的接收者被声明为 BaseTemaplte,尽管 obj 的 Class 是 AddSample。InvokeExact 需要精确的参数匹配。
我的问题可能会简化为:如何将实例从其基本类型转换为动态加载的子类型?
将obj的声明类型更改为动态加载的AddSample..?
UPDATE:
使用 cast 无助于解决与先前结果相同的问题。原因仍然是给定的参数与 myMH 声明不完全匹配。当我检查生成的字节码时会更清楚:
myMH 指向
(AddSample,String,int,float)int
,但给定参数:
(Object, String, int, float)
,这会导致我之前显示的运行时错误。
谢谢
java - 如何在 JDK 6 中使用方法句柄?
这里的情况很奇怪。我需要多次调用相同的类实例方法(1000/秒范围),但无法导入或构建所需的库。我试图在我的 JEE 项目中调用一个方法,该方法使用应用程序服务器提供的库中的一个类。JEE 项目仍然需要在其他应用程序服务器上运行,因此我不能简单地针对该库进行构建。反思是我认为的唯一解决方案。
当速度如此之快时,使用反射的执行时间比直接调用慢几个数量级。
经过一番研究,我发现了 static final MethodHandles:
效果很好,让我得到了可接受的速度结果(慢 2-4 倍而不是慢 200 倍)。这个完美的解决方案似乎存在问题——我需要它在 Java 6 上运行(嘘,嘶嘶声,这是一个要求)
针对 1.6 进行编译时,我得到:
低于 1.7 的源级别不允许调用多态方法
在线上
是否有任何解决方案可以利用与 1.6 一起使用的 MethodHandle 的概念?
java - 为什么返回类型(强制转换)在 MethodHandler 性能中起关键作用?
我正在做一个简单的项目,需要检索一个 bean 属性。首先我使用反射。然后我对 invokedynamic 和 Method Handler 进行了一些调查以获得更好的性能。
虽然invokeExact
比反射快得多,但调用比反射慢得多。
测试环境:
- Win7 32位
- Java 7 U 80
- 核心由于 CPU 3.06GHZ
我得到的 tp/ms 是这样的:
这是性能测试输出(我运行了两次):
这是我的测试代码:
invokeExact
无法满足我的用例,因为我在编译时不知道确切的返回类型。似乎返回类型(强制转换)是MethodHandle
性能的关键。
这似乎不是预期的结果,因为它MethodType
具有确切的返回类型。为什么进行强制施法以提高性能仍然很重要?
是否有一些文档解释了这方面的细节?此外,是否有任何关于比较使用反射与方法处理程序的 impl 细节的文档?
java - 当 MethodHandle 更快时,为什么要使用反射来访问类成员?
随着 Java 7 的发布MethodHandle
,它允许用户调用一个方法,就像使用它的底层字节码一样。特别是,MethodHandles.Lookup
该类提供工厂方法来创建方法句柄以访问类成员:
Lookup 对象上的工厂方法对应于方法、构造函数和字段的所有主要用例。工厂方法创建的每个方法句柄都是特定字节码行为的功能等价物。
从功能上讲,这或多或少等同于使用反射来访问这些相同的类成员,但方法句柄比反射更快。
那么,是否有任何理由仍然使用反射功能,例如Field#get(..)
/Method.invoke(..)
或者这些方法是否随着引入更快的方法句柄而有效过时?
请注意,虽然方法句柄是在 Java 7 中引入的,但我的问题主要与 Java 8 相关,在 Java 8 中,它们被优化以达到与直接字段/方法调用大致相等的性能,超过了反射的能力。