gpt4 book ai didi

java - 使用 groovy 脚本引擎(GroovyClassLoader)运行包含新行 "\n"的 java 代码时出现 GroovyCastException

转载 作者:行者123 更新时间:2023-12-01 20:03:43 25 4
gpt4 key购买 nike

目前我正在研究一种以字符串形式运行java代码的方法。这就是我的做法。

import java.util.HashMap;
import java.util.Map;

import groovy.lang.GroovyClassLoader;

public class GroovyStackOverflow {

public static void main(String[] args) {
GroovyClassLoader gcl = new GroovyClassLoader();
String codeSnippet = "double calculatedAnswer = (Double)"
+ "contextMap.get(\"doubleValue\") * (Double)contextMap.get(\"doubleValue\");"
+ " calculatedAnswer = Math.sqrt(calculatedAnswer); "
+ "calculatedAnswer = calculatedAnswer * calculatedAnswer;"
+ "System.out.println(calculatedAnswer);"
+ " return calculatedAnswer;";
StringBuilder sb = new StringBuilder();
sb.append("public class ScriptImplementor implements ScriptEvaluator { public Object evaluate(Map contextMap) {");
sb.append(codeSnippet);
sb.append("} }");
Class<?> clazz = gcl.parseClass(sb.toString());
ScriptEvaluator scriptEvaluator = null;
double calculatedAnswer = 100.0;
try {
Map contextMap = new HashMap();
contextMap.put("doubleValue", (double)100.0);
contextMap.put("threadId", "thread"+100);
contextMap.put("hashCode", 100);
scriptEvaluator = (ScriptEvaluator) clazz.newInstance();
scriptEvaluator.evaluate(contextMap);;
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}

public interface ScriptEvaluator {
public Object evaluate(Map contextMap);
}

问题是在以下情况下失败。

import java.util.HashMap;
import java.util.Map;

import groovy.lang.GroovyClassLoader;

public class GroovyStackOverflow {

public static void main(String[] args) {
GroovyClassLoader gcl = new GroovyClassLoader();
String codeSnippet = "double calculatedAnswer = (Double)"
+ "\n "
+ "contextMap.get(\"doubleValue\") * (Double)contextMap.get(\"doubleValue\");"
+ " calculatedAnswer = Math.sqrt(calculatedAnswer); "
+ "calculatedAnswer = calculatedAnswer * calculatedAnswer;"
+ "System.out.println(calculatedAnswer);"
+ " return calculatedAnswer;";
StringBuilder sb = new StringBuilder();
sb.append("public class ScriptImplementor implements ScriptEvaluator { public Object evaluate(Map contextMap) {");
//sb.append(codeSnippet.replaceAll("\n", " "));
sb.append(codeSnippet);
sb.append("} }");
Class<?> clazz = gcl.parseClass(sb.toString());
ScriptEvaluator scriptEvaluator = null;
double calculatedAnswer = 100.0;
try {
Map contextMap = new HashMap();
contextMap.put("doubleValue", (double)100.0);
contextMap.put("threadId", "thread"+100);
contextMap.put("hashCode", 100);
scriptEvaluator = (ScriptEvaluator) clazz.newInstance();
scriptEvaluator.evaluate(contextMap);;
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
public interface ScriptEvaluator {
public Object evaluate(Map contextMap);
}

我不明白为什么会失败以及此错误消息的含义 -

Exception in thread "main" org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class java.lang.Double' with class 'java.lang.Class' to class 'double'
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToNumber(DefaultTypeTransformation.java:163)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.doubleUnbox(DefaultTypeTransformation.java:88)
at ScriptImplementor.evaluate(script15126616543572010791987.groovy:1)
at GroovyStackOverflow.main(GroovyStackOverflow.java:33)

取消注释此代码后 //sb.append(codeSnippet.replaceAll("\n", "")); 它可以工作。但请提出更好的处理方法。另外为什么它在解析类时不给出错误?像这样我还能期待什么其他惊喜?

最佳答案

您发现了 Java 和 Groovy 之间的差异。

在 Java 中,语句以分号结束。

在 Groovy 中,语句以分号结束,如果语句已经是完整的语句,则以换行符结束。

在您的情况下,这意味着代码

double calculatedAnswer = (Double)
contextMap.get("doubleValue") * (Double)contextMap.get("doubleValue")

有两个语句。

这些语句中的第一个是doublecalculatedAnswer = (Double)

在 Groovy 中,您还可以省略 .class 来引用类,因此 Double.class 可以写为 Double

因此,您在该语句中所做的是将 Double 类对象分配给 double 变量。这里的括号只是无操作。

这当然会失败,就像消息所说的那样,因为 Double 类对象无法自动将大小写转换为 double

您可以显式转义换行符,使其不会像这样结束语句

double calculatedAnswer = (Double)\
contextMap.get("doubleValue") * (Double)contextMap.get("doubleValue")

它会像你预期的那样工作。

但是当然也可能存在 Groovy 和 Java 不同的其他情况。

永远记住,Groovy 语法与 Java 语法很接近,但完全相同。

事实上,每个有效的 Java 代码也是有效的 Groovy 代码,但不一定具有与您在本示例中看到的完全相同的含义。

关于java - 使用 groovy 脚本引擎(GroovyClassLoader)运行包含新行 "\n"的 java 代码时出现 GroovyCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47699571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com