2016-08-19 1 views
1

Я пытаюсь создать консольный интерфейс для Java-программы с помощью Nashorn. Поэтому я хочу, чтобы некоторые данные были оценены в отношении некоторых импортных импортных товаров. Проблема заключается в том, когда он обращается к неопределенному значению. В идеале, engine.eval должен бросить ReferenceError или вернуть null, но я получаю противоречивые значения позже:Несогласованный вывод в Nashorn после доступа к неопределенному значению

import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x }")); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x = 1 }")); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x }")); 
    } 
} 

результат на ideone и Windows, Oracle JDK 1.8.0_101 является:

null 
1 
null 

последний выход - null, но добавление x == null дает false.

Я получаю этот вывод, если добавить пробелы в первой строке:

null 
1 
1 

кажется, что последнее значение null, если первая и последняя engine.eval параметры точно такие же, включая пробелы.

Значение x может вернуться между null и 1 так это выглядит как какой-то кэширование в двигателе:

import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x }")); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x = 1 }")); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x }")); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x }")); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x + x }")); 
     System.out.println(engine.eval("with(JavaImporter(java.util)) { x }")); 
    } 
} 

Дает:

null 
1 
null 
1 
2.0 
null 

Есть ли каким-то образом, чтобы получить эту последовательно дают результаты null, 1, 1?

+0

Значение 'x' is * неопределенный *, нет * null *. Он просто преобразуется в * null * на 'engine.eval', чтобы вернуть его в java. Вы пробовали 'x === undefined' (обратите внимание на' === ', а не' == ',' == 'просто ... плохо, в javascript. Это имеет очень непоследовательное поведение). –

+0

Я использовал '==', чтобы включить возможность «undefined» или «null», но не имеет значения, какой код я использую, какое-либо изменение, и оно снова рассматривается как «1». Замена 'x' на' x + x' дает 2, даже добавление пробела вокруг 'x' дает 1. Это похоже на то, что строка кэшируется движком и игнорирует любые изменения значения. – fgb

+0

Я думаю, что это может быть ошибка в nashorn при возврате в нестрогий режим (хотя я не нашел ссылок). Важно отметить, что синтаксис 'with (...) {...}' устарел и не поддерживается с помощью '' use strict ";'. Полностью удаление оператора 'with' делает nashorn жалуется, что переменная не была объявлена. – RudolphEst

ответ

0

Существует кэш класса в двигателе, который может быть отключен путем создания его:

NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); 
ScriptEngine engine = factory.getScriptEngine(new String[] { "--class-cache-size = 0" }); 

Заставив каждое выражение перекомпилировать, кажется, решить эту проблему. Похоже, что одно и то же выражение компилируется по-разному в зависимости от того, какие переменные находятся в области видимости.

0

Заставить двигатель признать объявление переменной.

Просто используйте var x в первом скрипте.

System.out.println(engine.eval("with(JavaImporter(java.util)) { var x }")); System.out.println(engine.eval("with(JavaImporter(java.util)) { x = 1 }")); System.out.println(engine.eval("with(JavaImporter(java.util)) { x }"));

 Смежные вопросы

  • Нет связанных вопросов^_^