1

异常的一般规则是在捕获一般异常之前先捕获更具体的异常。我有一个案例,关闭服务器抛出SocketException: socket closed来自我的侦听器IOException,但我不想在用户关闭服务器时向他们显示该消息。其他所有内容都可能是实际错误,因此应该向他们显示,因此我捕获SocketException,检查其消息,如果不是socket closed,则应将其重新抛出以被捕获并作为IOException. Java/NetBeans 7.0.1 似乎不喜欢这样。这是我的代码:

public void run() {
        while (runner == Thread.currentThread()) {
            System.out.println("waiting for connection...");
            try {
                Socket s = server.accept(); //throws SocketException/IOException
                if (session == null) {
                    session = new ReceiveSession(s, parent);
                } else {
                    s.close();
                }
            } catch (SocketException e) {
                if (!e.getMessage().equals("socket closed")) {
                    throw e; //error line, "unreported exception SocketException"
                }
            } catch (IOException e) {
                e.printStackTrace();
                parent.showError("Someone tried to connect but the connection failed: " + e);
                session = null;
            }
        }

    }

在尝试清理和构建时,我得到:

error: unreported exception SocketException; must be caught or declared to be thrown
                throw e;
1 error

既然是SocketExceptionextends IOException,就应该被抓的比较普遍IOException。为什么我会收到此错误?(顺便说一句,在 NetBeans 中按原样运行项目可以完美运行,当服务器按照我的意愿关闭时,它不会向用户显示异常。)

4

3 回答 3

6

你在throw之外try,所以抛出的异常不会catch下面的处理。

于 2013-01-04T09:58:19.447 回答
4

第二个捕获不会捕获重新抛出,因为它没有被扔到try第二个捕获负责的块中。您需要重构代码。


例如,最直接的重组是这样的:

public void run() {
    while (runner == Thread.currentThread()) {
        System.out.println("waiting for connection...");
        try {
            try {
                Socket s = server.accept(); //throws SocketException/IOException
                if (session == null) {
                    session = new ReceiveSession(s, parent);
                } else {
                    s.close();
                }
            } catch (SocketException e) {
                if (!e.getMessage().equals("socket closed")) {
                    throw e; //error line, "unreported exception SocketException"
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            parent.showError("Someone tried to connect but the connection failed: " + e);
            session = null;
        }
    }
}

嵌套的尝试让我哭了一点,但它可以完成工作(老实说,在我的脑海中,我想不出一个不会走得太远的更好方法)。

于 2013-01-04T09:58:20.727 回答
0

Catch 语句从它们各自的 try 块中捕获异常,而不是从列表中的其他 catch 块中捕获异常。您从 try 之外抛出异常,因此它不会被后续的 catch 块捕获。

于 2013-01-04T10:02:54.163 回答