未处理的异常:必须捕获或抛出 IOException

unhandled exception: IOException must be caught or thrown

所以最近我开始在 Java 中创建自己的 IRC client/server。 NetBeans 说我有一个未处理的 IOException。但是,查看我的代码,我执行了一个捕获 IOException 的 try-catch 块。这是我的代码:

package some.package.name;


import java.io.IOException;
import java.net.ServerSocket;

public class IRCServer extends ServerSocket {

    private ServerSocket server;
    private int port;

    /**
     * <p>Main constructor. Provides default port of 6667</p>
     */
    public IRCServer() {
        this(6667);
    }

    /**
     * <p>Secondary constructor. Uses port defined by either user or Main constructor</p>
     *
     * @param port The port to listen to for the server
     */
    public IRCServer(int port) { //This is where NetBeans show the error
        this.port = port;
        try {
            server = new ServerSocket(port);
        } catch (IOException e) {
            System.err.println("IOException caught\n" + e.toString());
        }
    }

    /**
     * <p>Overrides parent String toString()</p>
     *
     * @return PORT the server is listening to
     */
    @Override
    public String toString() {
        return "PORT: " + this.port;
    }
}

请注意 try...catch 中的 IOException 实际上是 java.io.IOExecption

编译错误是什么原因?

编辑:我在 Eclipse 中尝试过相同的代码,并通过 cmd 编译它。它仍然给出相同的错误

您的问题是您的 class 既扩展了 ServerSocket 又具有 ServerSocket 字段。这意味着对于 IRCServer 的每个实例,理论上您都有 两个 ServerSocket 个实例。一个是 IRCServer 本身,因为它扩展了它,一个是你命名为 server.

的嵌入式 ServerSocket

这本身就是一个严重的设计问题 - 如果您实际上并不以任何方式依赖其原始功能,则无需扩展 class。如果您打算将 IRCServer 用作 ServerSocket,则不应再嵌入一个。this 将成为您的 server

但导致编译错误的问题是每个构造函数都隐式或显式调用了super()构造函数。如果原来的 class 有一个无参数的构造函数 - 它确实如此 - 那么如果你自己调用 super(...) 失败,它将为你完成。

然而,ServerSocket 的构造函数声明为:

public ServerSocket() throws IOException

public ServerSocket(int port) throws IOException

这意味着对 super() 构造函数的隐式调用发生在 之前 您的 try...catch,它会抛出一个已检查的异常。这意味着您必须将自己的构造函数声明为 throws IOException,因为无法用 try...catch.

包围 super() 调用

我的建议是适当地扩展 class 或委托而不扩展。正确扩展意味着没有 server 变量。你的构造函数看起来像:

/**
 * <p>Main constructor. Provides default port of 6667</p>
 */
public IRCServer() throws IOException {
    this(6667);
}

/**
 * <p>Secondary constructor. Uses port defined by either user or Main constructor</p>
 *
 * @param port The port to listen to for the server
 */
public IRCServer(int port) throws IOException {
    super(port);
    this.port = port;
}

并且适当地委派意味着保留大部分原始代码但删除 extends ServerSocket,然后您将无法将 IRCServer 多态地用作 ServerSocket