问题标签 [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 投票
2 回答
2427 浏览

java - 为什么我不能 .invokeExact() 在这里,即使 MethodType 是好的?

对于我的一个项目,我必须动态调用构造函数。但由于这是 Java 7,而不是“经典”反射 API,我使用 java.lang.invoke。

代码:

好的,这行得通。

我遇到的问题是这条线:

如果我替换invokeinvokeExact,我会得到这个堆栈跟踪:

我不太明白。GlobPathMatcher和都RegexPathMatcher使用一个带有 aString作为参数的构造函数,MethodType因此 for both 是在 中定义的CONSTRUCTOR_TYPE。如果不是这样,我无论如何都无法“抓住” MethodHandles。

然而我得到一个WrongMethodTypeException. 为什么?


编辑:这是我阅读答案后的代码;现在我不需要中间地图:我只需要一张地图,将 a 映射String到 a MethodHandle

0 投票
1 回答
7526 浏览

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.

0 投票
0 回答
58 浏览

java - 用于 Lambda 方法引用的可理解 toString

有没有办法让toString使用方法句柄生成的 lambda 可以理解?在 Java 8 之前,我一直在使用FunctionGuava 的接口,并创建了一个脚本,为我的许多数据类生成函数。我还包括一个toString清楚地标识它的类和方法,例如,'MyItem::getPrice'。

然而,在 Java 8 中,虽然声明函数变得更加容易,但我现在无法确定函数是什么。nice 最重要的原因toString是出于调试目的,但我相信还有其他原因。如果这些信息可以通过反射获得,那就太好了,但显然不是。

此代码段

生产

正如你所看到的,甚至没有一些 lambda 超类可以使用。

澄清

不是在问我如何定义我自己的toString,而是我如何确定这个 lambda 调用的类/方法。定义我自己的toString会破坏使用 Java 8 lambdas 的全部目的,因为我需要做更多容易错字的工作才能获得一个像样的toString. 我还不如只使用没有 lambdas 的自动化脚本。

0 投票
1 回答
415 浏览

java - MethodHandle InvokeExact 参数

我对方法句柄的方法参数感到困惑。我先构建一个guardwithtest方法句柄如下图:

对我来说,问题是如何将参数传递给三个方法句柄:test、trueTarget 和 faliover。1、invokeExact的第一个参数“result”作为receiver传递给test guard,第二个参数“data”传递给startWith:

但是这三个参数被传递给 falseTarget 为:

那么,参数传递的规则是什么,它们如何与方法句柄引用的方法匹配?

0 投票
2 回答
320 浏览

java - MethodHandle 的 MethodType 转换以接受 Array Object 参数

我想适应String.startsWithfrom (String, String)booleanto (String[])boolean,以便它可以接受String[]参数,其中前两个参数将映射到(String, String). 因此,我写了下面的示例代码:

MethodHandletoString.startsWith适应boolean (String[])于最初的适应。但结果表明adapt.invokeExact失败。

堆栈跟踪中的新(String[])对象非常令人困惑。任何人都可以就如何解决它提供一些建议吗?

谢谢

这个问题可以抽象为:如何适应一个Methodhandle只接受的(String, String)boolean,以便它可以接受(String[])boolean参数?

0 投票
1 回答
361 浏览

java - 使用方法句柄转发功能接口上的调用

TL;DR: 我试图找到最有效的方法来动态创建功能接口的实现,该接口将调用转发到该接口的一组实例。

目标是简化接口的实现,允许客户端代码通过将处理程序(实现为功能接口)传递给适当的注册函数来为多个事件注册自己。一个例子:

这可以是这种界面的一个示例。会有很多这样的接口,每个接口都有不同的事件,所以实现应该尽可能简单,没有太多重复的代码。Event我想通过在这样的实现中引入一种供内部使用的类型,这可能最好地实现,它允许将调用转发到所有注册的处理程序:

的实现TrainStation可能如下所示:

这是所需代码的可管理级别。它的大部分可以提取到一个抽象类中,因此每个接口只需要一次。当然,任何减少它的方法都是一个加号,但如果不暴露Event实例,我看不到直接的方法。

继续使用这种方法,有趣的是接口的实现Event。我当然可以想象用普通的旧反射来做这件事,它的表现可以接受但不是很出色。但我认为,对于 Java 1.7 或 1.8,现在应该有一种更有效和/或更直接的方式来实现Event.getMasterHandler()使用新 API 的返回值,尤其是MethodHandle,因为我们知道每个处理程序接口都是一个函数式接口。我该怎么做呢?

0 投票
2 回答
432 浏览

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),这会导致我之前显示的运行时错误。

谢谢

0 投票
1 回答
492 浏览

java - 如何在 JDK 6 中使用方法句柄?

这里的情况很奇怪。我需要多次调用相同的类实例方法(1000/秒范围),但无法导入或构建所需的库。我试图在我的 JEE 项目中调用一个方法,该方法使用应用程序服务器提供的库中的一个类。JEE 项目仍然需要在其他应用程序服务器上运行,因此我不能简单地针对该库进行构建。反思是我认为的唯一解决方案。

当速度如此之快时,使用反射的执行时间比直接调用慢几个数量级。

经过一番研究,我发现了 static final MethodHandles:

效果很好,让我得到了可接受的速度结果(慢 2-4 倍而不是慢 200 倍)。这个完美的解决方案似乎存在问题——我需要它在 Java 6 上运行(嘘,嘶嘶声,这是一个要求)

针对 1.6 进行编译时,我得到:

低于 1.7 的源级别不允许调用多态方法

在线上

是否有任何解决方案可以利用与 1.6 一起使用的 MethodHandle 的概念?

0 投票
1 回答
185 浏览

java - 为什么返回类型(强制转换)在 MethodHandler 性能中起关键作用?

我正在做一个简单的项目,需要检索一个 bean 属性。首先我使用反射。然后我对 invokedynamic 和 Method Handler 进行了一些调查以获得更好的性能。

虽然invokeExact比反射快得多,但调用比反射慢得多。

测试环境:

  • Win7 32位
  • Java 7 U 80
  • 核心由于 CPU 3.06GHZ

我得到的 tp/ms 是这样的:

这是性能测试输出(我运行了两次):

这是我的测试代码:

invokeExact无法满足我的用例,因为我在编译时不知道确切的返回类型。似乎返回类型(强制转换)是MethodHandle性能的关键。

这似乎不是预期的结果,因为它MethodType具有确切的返回类型。为什么进行强制施法以提高性能仍然很重要?

是否有一些文档解释了这方面的细节?此外,是否有任何关于比较使用反射与方法处理程序的 impl 细节的文档?

0 投票
2 回答
6073 浏览

java - 当 MethodHandle 更快时,为什么要使用反射来访问类成员?

随着 Java 7 的发布MethodHandle,它允许用户调用一个方法,就像使用它的底层字节码一样。特别是,MethodHandles.Lookup该类提供工厂方法来创建方法句柄以访问类成员:

Lookup 对象上的工厂方法对应于方法、构造函数和字段的所有主要用例。工厂方法创建的每个方法句柄都是特定字节码行为的功能等价物。

从功能上讲,这或多或少等同于使用反射来访问这些相同的类成员,但方法句柄比反射更快

那么,是否有任何理由仍然使用反射功能,例如Field#get(..)/Method.invoke(..)或者这些方法是否随着引入更快的方法句柄而有效过时?

请注意,虽然方法句柄是在 Java 7 中引入的,但我的问题主要与 Java 8 相关,在 Java 8 中,它们被优化以达到与直接字段/方法调用大致相等的性能,超过了反射的能力。