2017-07-05 21 views
5

Tôi có một lớp học sau đây với một biến kiểu dàiNashorn: Javascript đánh giá biểu hiện ném lớp diễn viên ngoại lệ cho chức năng tiếp xúc sử dụng lambda

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; 
} 

} 

Tôi gọi phương pháp testLongValue từ JavaScript như sau cách

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))"); công trình

engine.eval("print(jsLong2(20))"); ném lớp diễn viên ngoại lệ

Tôi có thể làm engine.eval("print(jsLong2(20))"); làm việc cho loại dài

Exception dấu vết

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) 

Trả lời

0

Trước hết: Consumer đại diện cho phương pháp/chức năng mà không trả lại bất kỳ giá trị. Để in giá trị trả về Bạn nên sử dụng hàm.

Dù sao, việc sử dụng hàm sẽ gây ra cùng một ngoại lệ.

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

Phải rõ ràng đúc ở đâu đó trong mã Nashorn hoạt động cho int/long nhưng rõ ràng không hoạt động cho Integer/Long.

Để làm Ví dụ của bạn hoạt động Bạn có thể sử dụng LongUnaryOperator.

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

LongUnaryOperator sử dụng loại dài nguyên thay vì Long, để có thể truyền đến/từ số nguyên.

Bạn nên biết rằng không có 64 bit số nguyên trong JS nên đi dài để js thru Nashorn có thể gây ra một số isues:

Javascript long integer

Java 8/Javascript (Nashorn) long interoperatiblity

Các vấn đề liên quan