5

我有一个带有 Long 类型变量的以下类

package com.nm.poc;

public class JSLong{

private Long longValue;

public Long getLongValue() {
    return longValue;
}

public void setLongValue(Long longValue) {
    this.longValue = longValue;
}

public Long testLongValue(Long longValue){
    return longValue;
}

}

我从 JavaScript 调用方法 testLongValue 如下方式

package com.nm.poc;

import java.util.function.Consumer;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Main {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("nashorn");

    JSLong jsLong = new JSLong();

    //WORKS
    engine.put("jsLong", jsLong);     
    engine.eval("print(jsLong.testLongValue(20))");

    //Throws ClassCast Integer to Long
    engine.put("jsLong2", (Consumer<Long>)jsLong::testLongValue);
    engine.eval("print(jsLong2(20))");
   }
}

engine.eval("print(jsLong.testLongValue(20))");作品

engine.eval("print(jsLong2(20))");抛出类转换异常

我可以engine.eval("print(jsLong2(20))");为 Long 类型工作吗

异常跟踪

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at jdk.nashorn.internal.scripts.Script$1$\^eval\_.:program(<eval>:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(Unknown Source)
at com.nm.poc.Main.main(Main.java:20)
4

1 回答 1

0

首先:消费者代表不返回任何值的方法/函数。为了打印返回值你应该使用函数。

无论如何,使用 Function 会导致同样的异常。

//Throws ClassCast Integer to Long
engine.put("jsLong2", (Function<Long, Long>)jsLong::testLongValue);
engine.eval("print(jsLong2(20))");

Nashorn 代码中的某处必须有显式转换,它确实适用于 int/long,但显然不适用于 Integer/Long。

要使您的示例有效,您可以使用 LongUnaryOperator

//This works
engine.put("jsLong2",  (LongUnaryOperator)jsLong::testLongValue);
engine.eval("print(jsLong.testLongValue(20))");

LongUnaryOperator 使用原始 long 类型而不是 Long 类,因此可以将其转换为整数。

您应该知道 JS 中没有 64 位整数,因此通过 Nashorn 将 long 传递给 js 可能会导致一些问题:

Javascript长整数

Java 8/Javascript (Nashorn) 长互操作性

于 2017-08-04T15:52:55.407 回答