[英]How to use Nashorn? How it improve performance?
我最近開始學習nashorn。 我很驚訝地看到我們現在可以從我們的Java代碼運行javascript。 我想知道,如果我們使用JavaScript而不是整個Java代碼,它實際上會提高系統的性能。 會不會進行上下文切換來調用js並返回?
問題的另一部分:我嘗試創建一個測試項目,並且能夠從Java代碼運行js。
public class JSFromJava {
static class JavaClass {
int intValue;
String data;
long longValue;
public int getIntValue() {
return intValue;
}
public void setIntValue(int intValue) {
this.intValue = intValue;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public long getLongValue() {
return longValue;
}
public void setLongValue(long longValue) {
this.longValue = longValue;
}
@Override
public String toString() {
return "JavaClass [intValue=" + intValue + ", data=" + data
+ ", longValue=" + longValue + "]";
}
}
public static void main(String[] args) throws ScriptException, IOException, NoSuchMethodException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
// read script file
engine.eval(Files.newBufferedReader(Paths.get("e:/js/a.js"), StandardCharsets.UTF_8));
Invocable inv = (Invocable) engine;
// call function from script file
Object op = inv.invokeFunction("incrementValueByTen", 2);
System.out.println(op);
JavaClass jc = new JavaClass();
jc.intValue=2;
jc.longValue=56;
jc.data="data";
System.out.println(jc);
inv.invokeFunction("updateJavaObject", jc);
System.out.println(jc);
}
}
Javascript文件:
function incrementValueByTen(arg) {
return arg + 10;
}
function updateJavaObject(arg) {
print("arg recieved::::"+arg)
print(arg.getIntValue())
arg.setIntValue(5);
arg.data=incrementValueByTen(arg.data);
arg.longValue=incrementValueByTen(arg.longValue);
print("arg updated::::"+arg)
}
如我們所見,我正在嘗試更新Java對象或使用傳遞給第二個函數的Java對象。 我遇到問題,說arg沒有這些方法。 所有屬性也都為空。
第一種方法正在使用原始類型,因此效果很好。
這是否意味着我們不能將Java對象作為參數傳遞給任何方法?
請提出建議。
謝謝阿米特
這里的問題是JavaClass
不是公共的。 如果Java類不是公共的,則即使您將它們聲明為“公共”,其方法實際上也不是公共的,除非它們重寫了超類方法或實現了該類實現的接口方法。 這不是Nashorn特有的問題,通常是可以的,除非在公共超類或已實現的接口上聲明了公共方法,否則您不能在非公共類上調用公共方法。 如果將其更改為public static class JavaClass
,則應該能夠從JS調用其方法。
至於“上下文從JS切換到Java並返回”; 沒有這樣的事情。 Nashorn將JS程序編譯為Java字節碼類,並使用INVOKEDYNAMIC指令從JS調用Java方法。 HotSpot通常將其鏈接起來與INVOKEVIRTUAL一樣有效(這是已編譯的Java代碼將調用該方法進行的操作),但需要注意的是,在JS中,它實際上看起來完全不同。 例如,在Java中,它看起來像:
ALOAD 1
INVOKEVIRTUAL "int JavaClass.getIntValue()"
在納斯霍恩,實際上是
ALOAD 1
INVOKEDYNAMIC "dyn:getMethod:getIntValue"
ALOAD 1
INVOKEDYNAMIC "dyn:call"
(因此,有兩個INVOKEDYNAMIC:一個用於檢索類上的方法,另一個用於調用它;在JS中,所有方法調用都是這樣的兩步)。
您還可以使用屬性getter語法:
print(arg.intValue)
在這種情況下, arg.intValue
將編譯為
ALOAD 1
INVOKEDYNAMIC "dyn:getProp:intValue"
鏈接器機制知道將其轉換為對對象的getIntValue()
的調用。 因此,在可能的情況下,屬性getter語法實際上最終會編譯為較小的字節碼(請注意,這不一定會更快,但這是個不錯的選擇)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.