繁体   English   中英

Java用Groovy处理抛出异常的闭包

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM