Reputation: 89
So recently I have started work on my own IRC client/server in Java. NetBeans is saying that I have an unhandled IOException. However, looking at my code I do a try-catch block that catches the IOException. Here is my code:
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;
}
}
Note that the IOException
in the try...catch
is, indeed, java.io.IOExecption
.
What is causing the compilation error?
EDIT: I have tried the same code in both Eclipse and by compiling it via cmd. It is still giving the same error
Upvotes: 0
Views: 581
Reputation: 34618
Your problem is that your class both extends ServerSocket
and has a ServerSocket
field. This means that for every instance of IRCServer
you theoretically have two ServerSocket
instances. One is the IRCServer
itself, because it extends it, and one is the embedded ServerSocket
you named server
.
This in itself is a serious design problem - there is no need to extend a class if you are not actually relying on its original functionality in any way. And if you intended to use the IRCServer
as a ServerSocket
, you shouldn't have an additional one embedded in. this
becomes your server
.
But the issue that causes the compilation error is the fact that every constructor implicitly or explicitly calls the super()
constructor. If the original class had a no-args constructor - and it does - then if you fail to call super(...)
yourself, it will be done for you.
However, the constructors of ServerSocket
are declared as:
public ServerSocket() throws IOException
and
public ServerSocket(int port) throws IOException
This means that the implicit call to the super()
constructor happens right before your try...catch
, and it throws a checked exception. It means that you have to declare your own constructor as throws IOException
, as there is no way to surround a super()
call with try...catch
.
My advice would be either to extend the class properly or delegate without extending. Properly extending means no server
variable. And your constructors would look like:
/**
* <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;
}
And properly delegating would mean keeping most of your original code but removing the extends ServerSocket
, and then you will not be able to use IRCServer
polymorphically as a ServerSocket
.
Upvotes: 1