使用 Java 中定义的变量从字符串执行代码
Execute code from string with defined variables in Java
我有以下class
class ListNode
{
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
我的任务是编写一个方法:
- 将
int[]
作为参数。
- 反转数组。
- Returns
ListNode
具有数组中当前元素的值,具有新创建的 ListNode 的 .next
以及数组中的相应值等等。
给定 new int[]{0, 8, 7};
的输入,我希望得到一个 ListNode
,其中值为 7,.next
是一个值为 8 的新节点,最后 .next.next
是一个值为0的新节点。
我写了以下方法来实现这种行为
public static ListNode reverseAndLinkToListNode(int [] arrayToReverse)
{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
int finalDigitsArrayLength = arrayToReverse.length;
ListNode finalNode = new ListNode();
if (finalDigitsArrayLength > 0)
{
finalNode.val = arrayToReverse[finalDigitsArrayLength - 1];
int j = 1;
for (int i = finalDigitsArrayLength - 2; i >= 0; i--)
{
try
{
// create a new list node
ListNode newlyCreatedNode = new ListNode(arrayToReverse[i]);
// calculate how many 'nexts' I need
String codeToExecute = returnNumberOfNexts(j);
// set the next field with the list node I just created
engine.eval(codeToExecute);
}
catch (Exception e)
{
System.out.println(e);
}
j++;
}
}
return finalNode;
}
public static String returnNumberOfNexts(int nextCounter)
{
String finalDotNextString = "finalNode";
if (nextCounter > 0)
{
for (int i = 0; i < nextCounter; i++)
{
finalDotNextString += ".next";
}
}
finalDotNextString += " = newlyCreatedNode;";
return finalDotNextString;
}
上面的解决方案 returns 正确的代码可以执行,但是在执行时,我得到:
javax.script.ScriptException: ReferenceError: "finalNode" is not defined in <eval> at line number 1
如何在引擎中定义 finalNode
和 newlyCreatedNode
变量?
您的脚本引擎在尝试解析 'finalNode' 变量时失败。原因是 finalNode 在 Java 中是已知的,但在 Java 脚本引擎中是未知的。所以你需要告诉脚本引擎如何解析变量。我没有测试代码,但它可能看起来有点像这样:
ListNode finalNode = new ListNode();
ScriptEngine engine = manager.getEngineByName("js");
Bindings bindings = engine.getBindings(ScriptContext.GLOBAL_SCOPE);
if (bindings==null) {
bindings = engine.createBindings();
engine.setBindings(ScriptContext.GLOBAL_SCOPE);
}
bindings.put("finalNode", finalNode);
engine.eval(codeToExecute);
我有以下class
class ListNode
{
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
我的任务是编写一个方法:
- 将
int[]
作为参数。 - 反转数组。
- Returns
ListNode
具有数组中当前元素的值,具有新创建的 ListNode 的.next
以及数组中的相应值等等。
给定 new int[]{0, 8, 7};
的输入,我希望得到一个 ListNode
,其中值为 7,.next
是一个值为 8 的新节点,最后 .next.next
是一个值为0的新节点。
我写了以下方法来实现这种行为
public static ListNode reverseAndLinkToListNode(int [] arrayToReverse)
{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
int finalDigitsArrayLength = arrayToReverse.length;
ListNode finalNode = new ListNode();
if (finalDigitsArrayLength > 0)
{
finalNode.val = arrayToReverse[finalDigitsArrayLength - 1];
int j = 1;
for (int i = finalDigitsArrayLength - 2; i >= 0; i--)
{
try
{
// create a new list node
ListNode newlyCreatedNode = new ListNode(arrayToReverse[i]);
// calculate how many 'nexts' I need
String codeToExecute = returnNumberOfNexts(j);
// set the next field with the list node I just created
engine.eval(codeToExecute);
}
catch (Exception e)
{
System.out.println(e);
}
j++;
}
}
return finalNode;
}
public static String returnNumberOfNexts(int nextCounter)
{
String finalDotNextString = "finalNode";
if (nextCounter > 0)
{
for (int i = 0; i < nextCounter; i++)
{
finalDotNextString += ".next";
}
}
finalDotNextString += " = newlyCreatedNode;";
return finalDotNextString;
}
上面的解决方案 returns 正确的代码可以执行,但是在执行时,我得到:
javax.script.ScriptException: ReferenceError: "finalNode" is not defined in <eval> at line number 1
如何在引擎中定义 finalNode
和 newlyCreatedNode
变量?
您的脚本引擎在尝试解析 'finalNode' 变量时失败。原因是 finalNode 在 Java 中是已知的,但在 Java 脚本引擎中是未知的。所以你需要告诉脚本引擎如何解析变量。我没有测试代码,但它可能看起来有点像这样:
ListNode finalNode = new ListNode();
ScriptEngine engine = manager.getEngineByName("js");
Bindings bindings = engine.getBindings(ScriptContext.GLOBAL_SCOPE);
if (bindings==null) {
bindings = engine.createBindings();
engine.setBindings(ScriptContext.GLOBAL_SCOPE);
}
bindings.put("finalNode", finalNode);
engine.eval(codeToExecute);