立即重新抛出捕获的异常与抛出声明之间的区别

时间:2015-12-27 16:08:25

标签: java exception

public void init() throws SocketException
{
    try
    {
        socket = new DatagramSocket(4446);
    }
    catch (SocketException se)
    {
        throw se;
    }
}

public void init() throws SocketException
{
    socket = new DatagramSocket(4446);
}
  • 两个代码块是否基本相同,或者它们与调用此init方法的调用者的行为有何不同?
  • 此方法的调用者收到的异常是否具有相同的信息和完全相同的堆栈跟踪?

3 个答案:

答案 0 :(得分:2)

您将获得的堆栈跟踪将与通过简单实验可以轻松证明的完全相同。在代码执行方面,第一个示例中将对异常进行额外处理,但行为没有显着差异

如果需要捕获更深层的异常,通常将异常包含在新异常中并将原始异常用作参数,在这种情况下,您将获得两个堆栈跟踪 - 一个来自init( )和原来的例外中的一个。

throw new RuntimeException(se);

答案 1 :(得分:2)

从调用者的角度来看,它们是相同的,调用者必须捕获SocketException或添加抛出SocketException

唯一的问题是,在某些情况下,可能不允许调用方法在声明中使用throws,因为SocketException是一个经过检查的例外。

  

此方法的调用者收到的异常是否相同   信息和完全相同的堆栈跟踪?

是的,因为你没有从init()中抛出新的异常。

答案 2 :(得分:1)

根本没有差异,但有时,如果进程失败,您需要在重新抛出异常之前添加一些逻辑(比如关闭连接)。

public void init() throws SocketException {
    try {
        socket = new DatagramSocket(4446);
    } catch (SocketException se) {
        // damn, it failed, lets do something before throwing.
        throw se;
    }
}



正如@Ramanlfc指出的那样,有时你实现了一个接口,并且不能抛出已检查的异常。

@Override
public void init() {
    try {
        socket = new DatagramSocket(4446);
    } catch (SocketException e) {
        throw new RuntimeException("Failed to create DatagramSocket on port 4466", e);
    }
}

这里我们封装了异常,我们在stackstrace中添加了另一个级别。