Java Language
Moteur JavaScript Nashorn
Recherche…
Introduction
Nashorn est un moteur JavaScript développé en Java par Oracle, et a été libéré avec Java 8. nashorn permet d' incorporer le Javascript dans les applications Java via JSR-223 et permet de développer des applications autonomes Javascript, et il offre une meilleure performance d' exécution et une meilleure conformité à la ECMA spécification Javascript normalisée.
Syntaxe
- ScriptEngineManager // Fournit un mécanisme de découverte et d'installation pour les classes ScriptEngine; utilise une interface SPI (Service Provider Interface)
- ScriptEngineManager.ScriptEngineManager () // Constructeur recommandé
- ScriptEngine // Fournit l'interface au langage de script
- ScriptEngine ScriptEngineManager.getEngineByName (String shortName) // Méthode d'usine pour l'implémentation donnée
- Object ScriptEngine.eval (Script de chaîne) // Exécute le script spécifié
- Object ScriptEngine.eval (Reader Reader) // Charge puis exécute un script à partir de la source spécifiée
- ScriptContext ScriptEngine.getContext () // Retourne les liaisons, les lecteurs et le fournisseur d'écriture par défaut
- void ScriptContext.setWriter (Writer writer) // Définit la destination pour envoyer la sortie du script à
Remarques
Nashorn est un moteur JavaScript écrit en Java et inclus dans Java 8. Tout ce dont vous avez besoin est inclus dans le package javax.script
.
Notez que ScriptEngineManager
fournit une API générique vous permettant d'obtenir des moteurs de script pour différents langages de script (c.-à-d. Pas seulement Nashorn, pas seulement JavaScript).
Définir des variables globales
// 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
Bonjour 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
Exécuter le fichier 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!');
Intercepter la sortie du 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!'
Évaluer les chaînes arithmétiques
// 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.
Utilisation d'objets Java en JavaScript dans Nashorn
Il est possible de passer des objets Java au moteur Nashorn pour qu'ils soient traités en code Java. Dans le même temps, il existe des constructions spécifiques à JavaScript (et à Nashorn), et leur fonctionnement avec les objets Java n'est pas toujours clair.
Vous trouverez ci-dessous un tableau qui décrit le comportement des objets Java natifs dans les constructions JavaScript.
Constructions testées:
- Expression dans la clause if. Dans JS expression in, la clause if n'a pas besoin d'être booléenne contrairement à Java. Il est évalué comme faux pour ce que l'on appelle des valeurs de falsification (null, non défini, 0, chaînes vides, etc.)
- Pour chaque instruction, Nashorn a un type particulier de boucle - pour chacun - qui peut parcourir différents objets JS et Java.
- Obtenir la taille de l'objet Dans JS, les objets ont une longueur de propriété qui renvoie la taille d'un tableau ou d'une chaîne.
Résultats:
Type | Si | pour chaque | .longueur |
---|---|---|---|
Java null | faux | Pas d'itérations | Exception |
Chaîne vide Java | faux | Pas d'itérations | 0 |
Chaîne Java | vrai | Itère sur les caractères de chaîne | Longueur de la chaîne |
Entier Java / Long | valeur! = 0 | Pas d'itérations | indéfini |
Java ArrayList | vrai | Itère sur des éléments | Longueur de la liste |
Java HashMap | vrai | Itère sur les valeurs | nul |
Java HashSet | vrai | Itère sur les articles | indéfini |
Recommandations:
- Il est conseillé d'utiliser
if (some_string)
pour vérifier si une chaîne n'est pas nulle et non vide -
for each
peut être utilisé en toute sécurité pour parcourir n'importe quelle collection, et ne déclenche pas d'exceptions si la collection n'est pas itérable, nulle ou indéfinie - Avant d'obtenir la longueur d'un objet, il doit être vérifié pour null ou undefined (la même chose est vraie pour toute tentative d'appeler une méthode ou d'obtenir une propriété d'objet Java)
Implémentation d'une interface à partir d'un 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
}
}
Définir et obtenir des variables globales
// 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