问题标签 [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 回答
471 浏览

java - 从对象中私有的关键字段中获取 MethodHandle 列表

我有一个包含许多私有字段的对象列表,我想根据来自数据库的几个关键字段对它们进行分组。方法类在另一个包中。我的对象看起来像

关键字段可以是对象中字段的任意组合

我试图获取关键字段的 MethodHandle 列表。这个 MethodHandle 列表稍后将被流式传输并为 Collectors.groupingBy 调用以形成一个 Map。

但是,在为 MyObject 中的私有字段形成 MethodHandle 列表时,访问私有成员将出现非法访问异常。

我可以知道如何访问这些字段。谢谢!

编辑:我知道 Java 9 中有一个名为 privateLookupIn() 的方法,但我目前使用的是 Java 8。

0 投票
1 回答
244 浏览

java - 如何找出 lambda 适用于哪种方法?

如果使用 Java Lambda 表达式调用库中的方法,则这些通常只是封装的方法调用。是否有可能找出最初的方法,仅用于记录目的?(另一个问题是关于它适用于什么对象 - 这特别是关于被调用的方法。)

当调用 doSomethingInTransaction() 时,doInTransaction 方法实际上是使用 Runnable 类型的 Object 调用的。有时最好记录在此处传递的方法的名称和类(即 Foo.doSomething)以及对象。是否有可能通过反射或其他方式找出那是什么?如果这需要特定的 Java 版本,那也是一个有趣的答案。

(更新:请注意,这不是相关问题Java 8 - 如何访问封装为 lambda 的对象和方法的重复,因为我主要要求封装在那里的方法。那里没有问。)

0 投票
1 回答
211 浏览

java - 初始化静态块中的最终和非最终静态字段

在这里,我发现以下代码显示了 MethodHandles 和 Reflection 的性能差异:

这些是结果:

我不明白的是这行代码:

static_unreflect(final) 不等于unreflect(not final) 吗?那为什么他们在性能上表现出不同的结果呢?谁能解释一下?

0 投票
0 回答
114 浏览

java - 使用 LambdaMetaFactory 调用任意构造函数

假设我正在编写一个反序列化实用程序,并且希望性能比反射更好。

我有一个Map<Class, MethodHandle>,其中 MethodHandle 是给定类的所需构造函数。当用户调用T deserialize(ByteBuffer, Class<T>)时,它会从 Map 中获取相应的 MethodHandle,从缓冲区中获取构造函数参数,然后调用MethodHandle::invoke. 这很好用。

问题是,除非 MethodHandle 是static final,否则性能等同于反射。

有没有办法使用 LambdaMetaFactory 或 MutableCallSite 来提高性能?我看不到如何使用 LambdaMetaFactory(我们需要提前知道接口类型?),并且创建 MutableCallSite 仍然不是static final.

0 投票
2 回答
179 浏览

java - 我想打印 hi GrandFather;但它似乎打印 hi Father

我要打印hi GrandFather

但它似乎印喜父亲。而且我不明白如何区分和之间的findSpecial使用findVirtual

我希望有人可以帮助我。谢谢

控制台屏幕截图显示

0 投票
1 回答
1025 浏览

java - 使用 java MethodHandles 实现鸭子类型

我有两个类A,并且B都定义foo()了具有共同签名的方法(不接受任何内容,返回无效)。它们没有声明此方法的通用基类(或接口)。我想在 As 或 B 上调用这个方法,只要他们能响应这个调用。这种方法称为Duck Typing

我知道有一条指令叫做invokedynamic

invokedynamic 指令的每个实例称为动态调用站点。动态调用站点最初处于未链接状态,这意味着没有指定调用站点调用的方法。如前所述,动态调用站点通过引导方法链接到方法。动态调用站点的引导方法是编译器为动态类型语言指定的方法,JVM 调用一次以链接站点。从引导方法返回的对象永久确定调用站点的行为。

所以我尝试使用MethodHandles来实现这一点。这是示例:

当然,我有:

invokedynamic我清楚地看到和之间的区别MethodHanle。我看到问题在于fooMethodHandle 绑定到class A,而不是class B. invokedynamic但我有可能在这种特殊情况下以某种方式利用吗?

为什么我需要这个?这是我的小型研究项目的一部分。我正在尝试深入了解方法句柄,并且我想在从字段和方法中检索到的注释实例上调用常用方法。我无法在 Java 中为注释定义基类,因此不是使用实例化链和类强制转换或使用违反访问权限的反射检索这些值,如果可能的话,我想实现这种鸭子类型。

谢谢。

0 投票
1 回答
160 浏览

java - 有没有办法判断运行时类型是否被删除

这将是一个有点复杂的解释,但我会尝试。

假设你有一个泛型类:

getValue还有一个允许以反射方式调用的方法:

这是做什么的

  • 创建一个MethodHandle方法getValue

  • 调整它MethodHandle,以便我可以调用invokeExact它(否则我需要调用invoke它,这会更慢)。但这一步完全是可选的。

  • 一旦我建立MethodHandle,调用它。

现在让我们尝试调用它:

这应该有效,对吧?嗯,不。这将失败:

我明白为什么,因为is的擦除类型,所以调用应该是:T extends NumberNumber

这对我来说是显而易见的,但对我工作场所图书馆的来电者来说却不是,我不能责怪他们。请注意,这是一个简化的示例...


Box<Long> box = new Box<>();当他们使用Long类型构建时,提供Long.class进一步而不是Number.class. 解决方案显然是微不足道的,但是,我在想如果我可以(在运行时)“看到”返回类型getValue是泛型类型,我可以抛出一个正确的错误消息。例如:

换句话说,如果我可以在运行时判断返回类型是Number.classfromgetValue 并且它是某个erasure的结果,那么我在以后的决定中可能会更聪明一些。

那可能吗?

0 投票
0 回答
72 浏览

java - 为什么 MethodHandle 在 JDK 1.8 中比 Reflection 慢?

我有两个使用 JMH 的性能测试。代码很简单,一个是使用Java Reflection,一个是使用MethodHandle(JDK1.7中引入),顺便说一下,isEmptyMethod和MH_isEmpty被声明为static final,像这样:

` Java 反射:

` 方法句柄:

下图是性能结果: 性能结果

根据JDK文档。为什么 MethodHandle 不比 java 反射快?上面的代码有什么问题?

0 投票
2 回答
268 浏览

java - 使用 ByteBuddy 创建一个转换器以从代理添加一个类

我正在尝试从使用 ByteBuddy 实现的代理加载类。我在代理中定义了一个类,并希望将其加载到目标程序中。这是我的变压器的样子:

但是,此代码不起作用。它抛出以下错误:

堆栈跟踪如下所示:

在这个例子中,SourcePageFetcher是 targetClass 并且RemoveWebDriver是由TypeDescription.

这个类加载器的目标是加载类,这些类将成为Advice我为检测我的代码而创建的一些类的助手。我应该尝试以ClassInjector其他方式使用吗?还是我以错误的方式看到了问题,还是应该只使用另一个 ClassLoadingStrategy?

0 投票
1 回答
140 浏览

java - 将方法从文件转换为 LambdaExpression

我正在尝试将方法(从文件中读取)转换为 lambda 表达式,因此我可以测量执行该方法所需的时间,而忽略慢速 Method.invoke(...) 函数。

我一直在尝试使用 实现我的目标LambdaMetafactory,但老实说,我已经阅读了很多关于如何做到这一点的问题和解释,以至于我什至不知道我在做什么了。

假设参数和方法构造良好并且(这是棘手的部分)我必须动态处理涉及不同数量和类型参数的多个选项:

以及界面(对不起名称,我稍后会更改它):

这是尝试使用 lambda 执行该方法的代码:

我读过这篇文章,我不明白我在做什么好和错。你能帮我吗?

[编辑] 当前错误是: