Exception Groovy结束异常与引发的异常不同
我在Groovy中遇到了一个非常奇怪的行为。当我从脚本中的闭包抛出异常时,抛出的结束异常是不同的 以下是代码和详细信息:Exception Groovy结束异常与引发的异常不同,exception,groovy,Exception,Groovy,我在Groovy中遇到了一个非常奇怪的行为。当我从脚本中的闭包抛出异常时,抛出的结束异常是不同的 以下是代码和详细信息: public class TestDelegate { def method(Closure closure) { closure.setResolveStrategy(Closure.DELEGATE_FIRST); closure.delegate = this; closure.call(); }
public class TestDelegate {
def method(Closure closure) {
closure.setResolveStrategy(Closure.DELEGATE_FIRST);
closure.delegate = this;
closure.call();
}
public static void main(String[] args) {
// Make Script from File
File dslFile = new File("src/Script.dsl");
GroovyShell shell = new GroovyShell();
Script dslScript = shell.parse(dslFile);
TestDelegate myDelegate = new TestDelegate();
dslScript.metaClass.methodMissing = {
// will run method(closure)
String name, arguments ->
myDelegate.invokeMethod(name, arguments);
}
dslScript.metaClass.propertyMissing = {
String name ->
println "Will throw error now!"
throw new MyOwnException("errrrror");
}
dslScript.run();
}
}
class MyOwnException extends Exception {
public MyOwnException(String message) {
super(message);
}
}
Script.dsl:
method {
println a;
}
因此,计划是当我在TestDelegate
中运行main()
方法时,它将运行DSL脚本,该脚本调用方法method()
。在脚本中找不到它,它将调用methodMissing
,然后从myDelegate
调用method()
,然后调用闭包,将委托设置为testDelegate
。到目前为止,一切顺利。然后,闭包应该尝试打印出未定义的“a”,从而引发属性missing
,这将引发MyOwnException
但是,当我运行代码时,我得到以下输出:
Will throw error now!
Exception in thread "main" groovy.lang.MissingPropertyException: No such property: a for class: TestDelegate
现在,它一定已经到达了catch块,因为它打印了“现在将抛出错误!”它一定也抛出了MyOwnException
!但是在某种程度上,MyOwnException
被转换为missingpropertyxception
,我不知道为什么。有人知道吗
注意:如果我从
TestDelegate\35; method()
中删除closure.setResolveStrategy(closure.DELEGATE_FIRST)
,代码将按预期运行并抛出MyOwnException
。但是对于我的DSL项目,我确实需要setResolveStrategy(Closure.DELEGATE\u优先)
。我更愿意知道这一问题的根本原因,而不是仅仅删除一两行代码,然后在不了解原因的情况下查看它的工作情况。我认为这就是本质上发生的情况:使用委托优先解析策略,Groovy运行时首先尝试访问myDelegate
上的属性a
,这会导致丢失属性异常
,因为不存在此类属性。然后它尝试属性missing
,这会导致抛出MyOwnException
。最终,运行库放弃并重新调用遇到的第一个异常(设计决策),这恰好是MissingPropertyException
使用所有者优先解决策略,首先咨询propertyMissing
,因此MyOwnException
最终被收回
查看下面的堆栈跟踪和源代码可以提供更多证据。因此,除了先将解析策略设置为owner之外,没有其他方法可以解决此问题。根据您试图实现的目标,有不同的解决方法。例如,可以将属性missing移动到委托中。顺便说一下,实现基于脚本的DSL的一个好方法是使用自定义脚本基类。