Java Language
Silnik JavaScript Nashorn
Szukaj…
Wprowadzenie
Nashorn to silnik JavaScript opracowany w Javie przez Oracle, który został wydany wraz z Javą 8. Nashorn umożliwia osadzanie Javascript w aplikacjach Java za pośrednictwem JSR-223 i umożliwia tworzenie samodzielnych aplikacji JavaScript, a także zapewnia lepszą wydajność środowiska wykonawczego i lepszą zgodność z ECMA znormalizowana specyfikacja Javascript.
Składnia
- ScriptEngineManager // Zapewnia mechanizm wykrywania i instalacji klas ScriptEngine; używa interfejsu SPI (Service Provider Interface)
- ScriptEngineManager.ScriptEngineManager () // Zalecany konstruktor
- ScriptEngine // Zapewnia interfejs do języka skryptowego
- ScriptEngine ScriptEngineManager.getEngineByName (String shortName) // Metoda fabryczna dla podanej implementacji
- Object ScriptEngine.eval (String script) // Wykonuje określony skrypt
- Object ScriptEngine.eval (Reader reader) // Ładuje, a następnie wykonuje skrypt z określonego źródła
- ScriptContext ScriptEngine.getContext () // Zwraca domyślnego dostawcę powiązań, czytników i pisarzy
- void ScriptContext.setWriter (Writer writer) // Ustawia miejsce docelowe, do którego wysyłane są dane wyjściowe skryptu
Uwagi
Nashorn to silnik JavaScript napisany w Javie i zawarty w Javie 8. Wszystko, czego potrzebujesz, znajduje się w pakiecie javax.script
.
Zauważ, że ScriptEngineManager
zapewnia ogólny interfejs API pozwalający uzyskać silniki skryptów dla różnych języków skryptowych (tj. Nie tylko Nashorn, nie tylko JavaScript).
Ustaw zmienne globalne
// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// Define a global variable
engine.put("textToPrint", "Data defined in Java.");
// Print the global variable
try {
engine.eval("print(textToPrint);");
} catch (ScriptException ex) {
ex.printStackTrace();
}
// Outcome:
// 'Data defined in Java.' printed on standard output
Cześć Nashorn
// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// Execute an hardcoded script
try {
engine.eval("print('Hello Nashorn!');");
} catch (ScriptException ex) {
// This is the generic Exception subclass for the Scripting API
ex.printStackTrace();
}
// Outcome:
// 'Hello Nashorn!' printed on standard output
Uruchom plik JavaScript
// Required imports
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.io.FileReader;
import java.io.FileNotFoundException;
// Obtain an instance of the JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// Load and execute a script from the file 'demo.js'
try {
engine.eval(new FileReader("demo.js"));
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (ScriptException ex) {
// This is the generic Exception subclass for the Scripting API
ex.printStackTrace();
}
// Outcome:
// 'Script from file!' printed on standard output
demo.js :
print('Script from file!');
Wyjście skryptu przechwytującego
// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// Setup a custom writer
StringWriter stringWriter = new StringWriter();
// Modify the engine context so that the custom writer is now the default
// output writer of the engine
engine.getContext().setWriter(stringWriter);
// Execute some script
try {
engine.eval("print('Redirected text!');");
} catch (ScriptException ex) {
ex.printStackTrace();
}
// Outcome:
// Nothing printed on standard output, but
// stringWriter.toString() contains 'Redirected text!'
Oceń ciągi arytmetyczne
// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
//String to be evaluated
String str = "3+2*4+5";
//Value after doing Arithmetic operation with operator precedence will be 16
//Printing the value
try {
System.out.println(engine.eval(str));
} catch (ScriptException ex) {
ex.printStackTrace();
}
//Outcome:
//Value of the string after arithmetic evaluation is printed on standard output.
//In this case '16.0' will be printed on standard output.
Wykorzystanie obiektów Java w JavaScript w Nashorn
Możliwe jest przekazywanie obiektów Java do silnika Nashorn w celu przetworzenia w kodzie Java. Jednocześnie istnieją pewne konstrukcje specyficzne dla JavaScript (i Nashorn) i nie zawsze jest jasne, jak działają z obiektami Java.
Poniżej znajduje się tabela opisująca zachowanie rodzimych obiektów Java wewnątrz konstrukcji JavaScript.
Testowane konstrukcje:
- Wyrażenie w klauzuli if. W wyrażeniu JS w klauzuli if nie musi być boolean, w przeciwieństwie do Javy. Jest to oceniane jako fałsz dla tak zwanych wartości fałszowania (zero, niezdefiniowane, 0, puste ciągi itp.)
- dla każdej instrukcji Nashorn ma specjalną pętlę - dla każdej - która może iterować po różnych obiektach JS i Java.
- Pobieranie rozmiaru obiektu. W JS obiekty mają długość właściwości, która zwraca rozmiar tablicy lub łańcucha.
Wyniki:
Rodzaj | Gdyby | dla każdego | .długość |
---|---|---|---|
Java null | fałszywy | Bez iteracji | Wyjątek |
Pusty ciąg Java | fałszywy | Bez iteracji | 0 |
Ciąg Java | prawdziwe | Iteruje po ciągach znaków | Długość sznurka |
Java Integer / Long | wartość! = 0 | Bez iteracji | nieokreślony |
Java ArrayList | prawdziwe | Iteruje po elementach | Długość listy |
Java HashMap | prawdziwe | Iteruje ponad wartościami | zero |
Java HashSet | prawdziwe | Iteruje po przedmiotach | nieokreślony |
Zalecenia:
- Wskazane jest użycie
if (some_string)
aby sprawdzić, czy łańcuch nie jest pusty i nie jest pusty -
for each
może być bezpiecznie używany do iteracji w dowolnej kolekcji i nie stwarza wyjątków, jeśli kolekcja nie jest iterowalna, zerowa lub niezdefiniowana - Przed uzyskaniem długości obiektu należy sprawdzić, czy jest pusta lub niezdefiniowana (to samo dotyczy każdej próby wywołania metody lub uzyskania właściwości obiektu Java)
Implementowanie interfejsu ze skryptu
import java.io.FileReader;
import java.io.IOException;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class InterfaceImplementationExample {
public static interface Pet {
public void eat();
}
public static void main(String[] args) throws IOException {
// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
try {
//evaluate a script
/* pet.js */
/*
var Pet = Java.type("InterfaceImplementationExample.Pet");
new Pet() {
eat: function() { print("eat"); }
}
*/
Pet pet = (Pet) engine.eval(new FileReader("pet.js"));
pet.eat();
} catch (ScriptException ex) {
ex.printStackTrace();
}
// Outcome:
// 'eat' printed on standard output
}
}
Ustaw i uzyskaj zmienne globalne
// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
try {
// Set value in the global name space of the engine
engine.put("name","Nashorn");
// Execute an hardcoded script
engine.eval("var value='Hello '+name+'!';");
// Get value
String value=(String)engine.get("value");
System.out.println(value);
} catch (ScriptException ex) {
// This is the generic Exception subclass for the Scripting API
ex.printStackTrace();
}
// Outcome:
// 'Hello Nashorn!' printed on standard output