![](/img/trans.png)
[英]closures in groovy vs closures in java 8 (lambda expressions)?
[英]Java with Groovy handling of closures throwing Exceptions
我们有一个可以使用groovy脚本进行自定义的系统,我发现这些脚本抛出的异常类型有一个非常奇怪的影响。
我们有一个groovy脚本,包含以下内容:
process {
throw new Exception("weeee")
}
进程被定义为脚本基类中的Closure:
public abstract class ScriptBaseClass extends Script {
Closure process;
public void process( Closure code ) {
process = (Closure) code.clone();
}
}
在实际运行脚本的Java类中 ,我们有以下方法(省略了所有设置代码,因为它似乎不相关):
public void process() {
try {
script.process.call();
} catch (Exception e) {
logger.debug("exception thrown from groovy script", e);
throw e;
}
}
请注意,此处的处理方法不会声明它会抛出任何异常。 然而,很明显它重新抛出了它捕获的异常e。 这段代码是有效的,它编译和运行非常愉快。 它按我的意愿抛出异常。
有谁知道这是合法代码? 从理论上讲,我不应该从一个没有声明它抛出它的方法中抛出一个已检查的异常。
它的工作原理是因为Java编译器(从Java 7开始)可以确定重新抛出的异常。 对于catch (Exception e)
它认为它是RuntimeException
因为在call()
中没有声明其他(已检查)异常。
你可以在那里阅读它,例如: https : //docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
所以这段代码完美编译:
public void xxxxx() {
try {
System.out.println('Hi!'); //or anything else w/o declared exceptions
} catch (Exception e) {
throw e;
}
}
Java编译看到只能在这里捕获RuntimeException,所以它不会要求你声明任何东西。
但为此:
public void xxxxx() {
try {
throw new IOException(); //or anything that have declared checked exception
} catch (Exception e) {
throw e;
}
}
它将无法编译,因为可以捕获并重新抛出IOException
Groovy和JVM并不真正关心被检查的异常。 这里只有Java编译器关心它。 事实上,你可以在任何RuntimeException或其父类(其中Exception是一个)上使用catch,而不要求它被声明为从try-block中调用的东西抛出。 所以编译器可以捕获Exception或Throwable。 当然,从程序逻辑的角度来看,这是完全不同的事情。
引入闭包或Groovy相关的任何内容都是不必要的复杂性。 以下是有效的Java代码:
public class Demo {
public void someMethod() {
try {
System.out.println("Hello");
} catch (Exception e) {
throw e;
}
}
}
请注意,以下内容无效且无法编译:
import java.sql.*;
public class Demo {
public void someMethod() {
try {
Connection c = DriverManager.getConnection("", "", "");
} catch (SQLException e) {
throw e;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.