未处理的异常:必须捕获或抛出 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
。
所以最近我开始在 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
。