Tôi biết bạn có thể làm việc với các mảng Java trong Nashorn và có rất nhiều ví dụ về cách thực hiện điều này. Vấn đề đối với tôi với cách tiếp cận tiêu chuẩn là nó làm cho mã javascript nhận thức rõ ràng về môi trường thời gian chạy của nó. Hiện tại tôi có một giải pháp sử dụng Rhino và nó liên tục chuyển đổi giữa các kiểu Java và các kiểu JavaScript gốc.Liền mạch truyền các mảng và danh sách đến và đi từ Nashorn
Đối với tê giác, tôi đã thực hiện điều này bằng cách triển khai org.mozilla.javascript.ContextFactory
và org.mozilla.javascript.WrapFActory
và đặt WrapFactory
trên số Context
khi gọi makeContext
. Việc thực hiện WrapFactory này đảm nhiệm việc chuyển đổi giữa các mảng Java và các danh sách và các mảng và danh sách JavaScript gốc. Nó cũng đề cập đến việc tôi phải lấy mã nguồn Rhino từ JDK để có được cách tiếp cận này để làm việc.
Tôi cần tìm một giải pháp tương tự cho Nashorn. Đây là một ví dụ về những gì tôi đang cố gắng hoàn thành.
public static void main(String args[]) {
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine();
try {
engine.eval("function print_array(arr) { print(arr); }");
engine.eval("function print_native() { print_array([1, 2, 3, 4]); }");
Invocable invocable = (Invocable) engine;
invocable.invokeFunction("print_array", new int[]{1, 2, 3, 4});
invocable.invokeFunction("print_array", Arrays.asList(1, 2, 3, 4));
invocable.invokeFunction("print_native");
} catch (ScriptException | NoSuchMethodException e) {
e.printStackTrace();
}
}
Kết quả của mã này là
[Tôi @ 169e6180
[1, 2, 3, 4]
1,2,3,4
Tôi đang tìm cách triển khai ScriptObjectMirror, giả sử rằng đó là chính xác, điều đó sẽ làm cho đầu ra trong số ba cuộc gọi invokeFunction
này giống nhau.
Tôi đã cố gắng sử dụng wrap
chức năng trên ScriptUtils
, nhưng vẫn kết quả là sai
CẬP NHẬT
tôi đã cố gắng để tạo ra một proxy năng động của loại Invocable
và làm chuyển đổi trong InvocationHandler
. Để tạo ra một NativeArray với Nashorn có vẻ như bạn nên sử dụng jdk.nashorn.internal.objects.Global.allocate
, nhưng điều này luôn luôn làm tăng một ngoại lệ.
Global.allocate(new int[] {1, 2, 3, 4})
Tăng
Exception in thread "main" java.lang.NullPointerException
at jdk.nashorn.internal.objects.Global.instance(Global.java:491)
at jdk.nashorn.internal.objects.NativeArray.<init>(NativeArray.java:141)
at jdk.nashorn.internal.objects.Global.allocate(Global.java:1584)
của bạn 'Arrays.asList() 'gọi dường như để tạo ra một danh sách với một yếu tố duy nhất của loại 'int []' thay vì những gì bạn muốn. Hãy thử 'Arrays.asList (1,2,3,4)' thay thế. – biziclop
ah, cảm ơn :) Điều đó làm cho mọi thứ tốt hơn một chút. Tôi sẽ cập nhật câu hỏi – Leon
Vấn đề chính ở đây là các mảng JS không thực sự là mảng theo nghĩa Java?Chúng giống các bản đồ với khóa 'int' hơn. – biziclop