Java Language
Motore JavaScript Nashorn
Ricerca…
introduzione
Nashorn è un motore JavaScript sviluppato in Java da Oracle ed è stato rilasciato con Java 8. Nashorn consente l'integrazione di Javascript in applicazioni Java tramite JSR-223 e consente di sviluppare applicazioni JavaScript standalone e offre migliori prestazioni di runtime e una migliore conformità con ECMA specifica Javascript normalizzata.
Sintassi
- ScriptEngineManager // Fornisce un meccanismo di individuazione e installazione per le classi ScriptEngine; utilizza un SPI (Service Provider Interface)
- ScriptEngineManager.ScriptEngineManager () // Costruttore consigliato
- ScriptEngine // Fornisce l'interfaccia per il linguaggio di scripting
- ScriptEngine ScriptEngineManager.getEngineByName (String shortName) // Metodo factory per la specifica implementazione
- Object ScriptEngine.eval (String script) // Esegue lo script specificato
- Object ScriptEngine.eval (Reader reader) // Carica e quindi esegue uno script dall'origine specificata
- ScriptContext ScriptEngine.getContext () // Restituisce il provider predefinito di binding, lettori e scrittori
- void ScriptContext.setWriter (writer writer) // Imposta la destinazione in cui inviare l'output dello script a
Osservazioni
Nashorn è un motore JavaScript scritto in Java e incluso in Java 8. Tutto ciò che serve è raggruppato nel pacchetto javax.script
.
Si noti che ScriptEngineManager
fornisce un'API generica che consente di ottenere motori di script per vari linguaggi di scripting (ovvero non solo Nashorn, non solo JavaScript).
Imposta variabili globali
// 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
Ciao 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
Esegui il file 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!');
Intercettare l'output dello script
// 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!'
Valuta le stringhe aritmetiche
// 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.
Utilizzo di oggetti Java in JavaScript in Nashorn
È possibile passare oggetti Java al motore Nashorn per essere elaborati nel codice Java. Allo stesso tempo, ci sono alcune costruzioni specifiche di JavaScript (e Nashorn), e non è sempre chiaro come funzionano con gli oggetti java.
Di seguito c'è una tabella che descrive il comportamento degli oggetti Java nativi all'interno delle costruzioni JavaScript.
Costruzioni testate:
- Espressione in se clausola. Nell'espressione JS la clausola if non deve essere di tipo booleano a differenza di Java. Viene valutato come falso per i cosiddetti valori falsy (null, indefinito, 0, stringhe vuote ecc.)
- per ogni istruzione Nashorn ha un tipo speciale di loop - per ciascuno - che può scorrere su diversi oggetti JS e Java.
- Ottenere dimensioni dell'oggetto. Negli oggetti JS è presente una lunghezza della proprietà, che restituisce le dimensioni di una matrice o di una stringa.
risultati:
genere | Se | per ciascuno | .lunghezza |
---|---|---|---|
Java null | falso | Nessuna iterazione | Eccezione |
Stringa vuota Java | falso | Nessuna iterazione | 0 |
Stringa Java | vero | Iterare su caratteri stringa | Lunghezza della corda |
Java Integer / Long | valore! = 0 | Nessuna iterazione | non definito |
Java ArrayList | vero | Itera sugli elementi | Lunghezza della lista |
Java HashMap | vero | Itera sopra i valori | nullo |
Java HashSet | vero | Fa scorrere gli oggetti | non definito |
Recommendatons:
- È consigliabile utilizzare
if (some_string)
per verificare se una stringa non è nullo e non vuota -
for each
può essere tranquillamente utilizzato per iterare su qualsiasi raccolta, e non genera eccezioni se la raccolta non è iterable, null o undefined - Prima di ottenere la lunghezza di un oggetto, è necessario controllarlo per null o undefined (lo stesso vale per qualsiasi tentativo di chiamare un metodo o ottenere una proprietà dell'oggetto Java)
Implementazione di un'interfaccia dallo script
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
}
}
Imposta e ottieni variabili globali
// 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