Java Nashorn中的(De)引用方法变体
(De)referencing method variant in Java Nashorn
考虑代码:
例 1
var Executors = java.util.concurrent.Executors;
var executor = Executors.newCachedThreadPool();
var fork = function (callable) {
// Clarify Runnable versus Callable overloaded methods
executor['submit(java.util.concurrent.Callable)'](callable);
};
fork(function(){ ... }); //ok
这行得通。
但这不起作用:
例 2
var Executors = java.util.concurrent.Executors;
var executor = Executors.newCachedThreadPool();
var fork = executor['submit(java.util.concurrent.Callable)'];
fork(function(){ ... }); //fails, NullPointerException
我认为,这是因为这里的fork
不是JS函数实例,它实际上是jdk.internal.dynalink.beans.SimpleDynamicMethod
的实例
我试图使用fork.apply(executor,function() { ... });
但本质上,简单动态方法没有apply
。
实际上,为什么示例 2 不起作用,而示例 1 有效?
这仅仅是纳索恩的福利吗?有没有比示例 1 更好的方法来定义 fork() 函数?
更新
在示例 2 中,
print(typeof fork);
报告function
print(fork)
报告[jdk.internal.dynalink.beans.SimpleDynamicMethod Future java.util.concurrent.AbstractExecutorService.submit(Callable)]
例外是(第 13 行读取 fork(function() {
)
Exception in thread "main" java.lang.NullPointerException
at jdk.nashorn.internal.scripts.Script$'^eval'_._L5(<eval>:13)
at jdk.nashorn.internal.scripts.Script$'^eval'_.runScript(<eval>:5)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:527)
不幸的是,目前你不能在 POJO 方法中使用 bind
、 apply
和 call
。我想将其添加为将来的增强功能。在上面的例子中,你目前能做的最好的事情是:
executor['submit(Callable)'](function() { ... })
请注意,虽然在一般情况下,对属性的索引访问(使用 []
运算符)的效率低于属性名称访问(使用 .
运算符),但 Nashorn 使用字符串文本识别索引访问,并将其视为与属性名称访问一样有效,因此您不会在这里遇到速度减慢,只是有点视觉噪音。在上面的情况下,它实际上最终会直接链接到执行者的虚拟方法。
说到视觉噪音,您不必完全限定java.util.concurrent.Callable
。当参数类型的非限定名称足以消除重载的歧义时(几乎总是如此),您可以只使用非限定名称,无论它在哪个包中(也适用于您自己的类)。
问题是您在调用中缺少接收方"执行器"。 一般来说,"获取"Java函数只适用于静态Java函数。例如:
jjs> var abs = java.lang.Math.abs;
jjs> abs(-10);
10
在您的示例中,我们可以将 fork 绑定到执行器并使其等效为静态。 此支持当前不存在。 如果从类中"获取",我们可能应该支持将接收器添加为第一个参数。 将为将来的版本提交增强请求。
Alex,
在示例 1 中,var fork
是一个返回数组 executor
的函数。在示例 2 中,var fork
是一个数组。这就是为什么你不能使用 ()
和apply
.
fork[0](function(){...})
对你有用吗?
谢谢
- 引用类变量中的原型方法
- 有没有一种方法可以通过只引用JavaScript来执行代码
- 可以“;超级“;可以在子类的方法内部使用,在不直接引用的情况下调用相应的超类方法
- 通过引用Javascript中的另一个函数来传递对象方法
- 这在 Object 方法中不引用对象,而是引用函数绑定到的标记
- 在方法中失去对对象的引用
- 使用clearInterval方法实现的是将区间变量引用设置为null,而不是
- 有没有一种方法可以捕获JavaScript控制台输出,以便我可以在其他地方引用它
- 有没有一种方法可以重新绑定jQuery插件中引用的事件处理程序
- 在JQuery中,'加载'方法'的相对路径在引用项目中的html文件时开始
- 可以't从客户端应用程序引用插件中定义的静态方法
- 更好的设计,以便从对象的方法引用自己的对象的属性
- 为什么Javascript库对数组方法(push,slice等)有本地引用
- 模仿通过引用而不是值将数字传递给函数的任何方法
- 从充当事件处理程序的多个方法引用对象属性
- 在 javascript 中将“this”引用传递给方法的提示
- Java Nashorn中的(De)引用方法变体
- 在 JavaScript 中,如何从更深层次的嵌套方法引用方法的返回值
- 如何从对象中引用方法
- 在init之前引用方法