Eri*_*uth 1 java groovy groovyshell
我对 Groovy 完全陌生,所以我希望答案并不明显......
假设我有一个脚本“Test.groovy”:
class A {
def greet() {println "Hey there!"}
}
new A().greet()
Run Code Online (Sandbox Code Playgroud)
我用GroovyShell(来自 Java)评估这个脚本:
new GroovyShell().evaluate(new File("Test.groovy"));
Run Code Online (Sandbox Code Playgroud)
我得到预期的输出:
嘿!
现在,我从脚本中删除最后一行,而是在对 的单独调用中对其进行评估evaluate(),我得到了一个非常模糊的异常。
“测试.groovy”:
class A {
def greet() {println "Hey there!"}
}
Run Code Online (Sandbox Code Playgroud)
爪哇:
GroovyShell shell = new GroovyShell();
shell.evaluate(new File("Test.groovy"));
shell.evaluate("new A().greet()");
Run Code Online (Sandbox Code Playgroud)
org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack:没有方法签名:A.main() 适用于参数类型:([Ljava.lang.String;) 值:[[]] 可能的解决方案:wait(), wait(long)、any()、find()、wait(long、int)、each(groovy.lang.Closure)
更有趣的是,如果我让脚本保持原样,只更改 Java 部分,它就可以完美运行(我得到两个“嘿那里!”)
这应该有助于解释您所看到的内容:http://www.groovy-lang.org/structural.html#_script_class
Groovy 将您的第一个 .groovy 文件视为脚本,因为最后一行存在于类声明之外。Groovy 编译为 Java 字节代码,而 Java 要求所有代码都在类中定义。main为了遵守这一规定,Groovy 施展了一些魔法,并使用类似于以下的方法将您的脚本动态转换为 Java 类:
public class script1440427072752 extends groovy.lang.Script {
public script1440427072752() {
}
public script1440427072752(groovy.lang.Binding context) {
super(context)
}
public static void main(java.lang.String[] args) {
org.codehaus.groovy.runtime.InvokerHelper.runScript(script1440427072752, args)
}
public java.lang.Object run() {
new A().greet()
}
}
public class A extends java.lang.Object {
public java.lang.Object greet() {
this.println('Hey there!')
}
}
Run Code Online (Sandbox Code Playgroud)
然而,当您删除该行时,Groovy 会将您的 .groovy 文件视为名为 的典型 Java 类A。无需动态翻译groovy.lang.Script。
当您尝试执行时A,GroovyShell 会查找一种main方法,但找不到,并抛出该错误。