Java Language
Двигатель JavaScript Nashorn
Поиск…
Вступление
Nashorn - это движок JavaScript, разработанный на Java Oracle и выпущенный с помощью Java 8. Nashorn позволяет внедрять Javascript в Java-приложения через JSR-223 и позволяет разрабатывать автономные приложения Javascript и обеспечивает лучшую производительность во время выполнения и лучшее соответствие ECMA нормализованная спецификация Javascript.
Синтаксис
- ScriptEngineManager // Обеспечивает механизм обнаружения и установки для классов ScriptEngine; использует SPI (интерфейс поставщика услуг)
- ScriptEngineManager.ScriptEngineManager () // Рекомендуемый конструктор
- ScriptEngine // Обеспечивает интерфейс для языка сценариев
- ScriptEngine ScriptEngineManager.getEngineByName (String shortName) // Заводский метод для данной реализации
- Object ScriptEngine.eval (String script) // Выполняет указанный скрипт
- Object ScriptEngine.eval (Reader reader) // Загружает и затем выполняет скрипт из указанного источника
- ScriptContext ScriptEngine.getContext () // Возвращает привязки по умолчанию, читателей и авторов
- void ScriptContext.setWriter (писатель писателя) // Устанавливает адресата для отправки вывода сценария в
замечания
Nashorn - это движок JavaScript, написанный на Java и включенный в Java 8. Все, что вам нужно, связано с пакетом javax.script
.
Обратите внимание, что ScriptEngineManager
предоставляет общий API, позволяющий получать скриптовые механизмы для различных языков сценариев (т.е. не только Nashorn, а не только JavaScript).
Установить глобальные переменные
// 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
Привет, Насорн
// 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
Выполнить файл 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!');
Выход перехвата скрипта
// 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!'
Оценка арифметических строк
// 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.
Использование объектов Java в JavaScript в Нашорне
Можно передавать объекты Java в механизм Nashorn для обработки в Java-коде. В то же время существуют некоторые конструкции JavaScript (и Nashorn), и не всегда ясно, как они работают с объектами Java.
Ниже приведена таблица, описывающая поведение собственных объектов Java внутри конструкций JavaScript.
Протестированные конструкции:
- Выражение в условии if. В выражении JS выражение if не должно быть логическим, в отличие от Java. Он оценивается как false для так называемых значений ложности (null, undefined, 0, пустые строки и т. Д.),
- для каждого утверждения Nashorn имеет особый тип цикла - для каждого - который может перебирать разные объекты JS и Java.
- Получение размера объекта. В объектах JS есть длина свойства, которая возвращает размер массива или строки.
Результаты:
Тип | Если | для каждого | .length |
---|---|---|---|
Java null | ложный | Нет итераций | исключение |
Пустая строка Java | ложный | Нет итераций | 0 |
Строка Java | правда | Итерации по строковым символам | Длина строки |
Java Integer / Long | значение! = 0 | Нет итераций | не определено |
Java ArrayList | правда | Итерации по элементам | Длина списка |
Java HashMap | правда | Итерирует значения | ноль |
Java HashSet | правда | Итерирует элементы | не определено |
Recommendatons:
- Целесообразно использовать
if (some_string)
чтобы проверить, не является ли строка пустой и не пустой -
for each
можно безопасно использовать для итерации по любой коллекции, и она не вызывает исключений, если коллекция не является итерируемой, нулевой или неопределенной - Перед тем, как получить длину объекта, он должен быть проверен как null или undefined (то же самое верно для любой попытки вызова метода или получения свойства объекта Java)
Внедрение интерфейса из скрипта
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
}
}
Установить и получить глобальные переменные
// 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