1

So I've got a thing like this:

try{ServerSocket acceptor = new ServerSocket(4782);}
catch(IOException e){System.err.println("ERROR: Couldn't listen on port 4782!");}
while (true)
{
    Socket clientSock = acceptor.accept();  


}

But when trying to assign clientSock, it says it can't find acceptor. When moving the acceptor out of the try block, it explodes with an unhandled exception.

Should I be putting a thing like Socket clientSock; before the try block?

Thanks.

1
  • (I think it's awesome that the Java language is specified to catch bugs like this, even if they are usually fixed incorrectly. I believe Alex disagrees with me.) Commented May 3, 2012 at 21:34

3 Answers 3

4

An alternative to what the other folks here have suggested: you could move more code into the try block:

try{
    ServerSocket acceptor = new ServerSocket(4782);

    while (true) {
        Socket clientSock = acceptor.accept();  
    }
} catch(IOException e){
    System.err.println("ERROR: Network problem:" + e.getMessage());
}

The advantage of doing things this way -- when you can get away with it -- is that the "happy path" reads more clearly; it's easier to follow what the code is supposed to do. The dark side of this approach is that it leads to lumping various error conditions together, so you can't react as specifically to individual problems. Sometimes, though, even that is an advantage rather than a problem.

Sign up to request clarification or add additional context in comments.

1 Comment

If you don't want that particular catch around the accept, you can throw an exception from the catch (an IOException would be appropriate), just return or a nested try-catch (may want to split across two small methods.
2

You can keep the instantiation in the try-catch but move the variable declaration out.

ServerSocket acceptor = null;
try{acceptor = new ServerSocket(4782);}
catch(IOException e){System.err.println("ERROR: Couldn't listen on port 4782!");}
while (true)
{
    Socket clientSock = acceptor.accept();  


}

6 Comments

Don't use nulls like that!! What happens if an IOException is thrown?
@TomHawtin-tackline I was respecting the original example in the question. It is indeed very bad to use null's like this. It's also bad to catch an IOException and then proceed to listen after you've been told the connection is bad.
@TomHawtin-tackline Why exactly is it bad to use nulls like that? Is there a loophole that makes unexpected behavior?
@SuperDisk In this particular example the program simply prints an error in the catch block and then continues, the code will therefore throw a NullPointerException when you call acceptor.accept()
@strawberry True, but that's a quickfix. Is there any other disadvantage to assigning null before actually initializing it?
|
1

No you should put the declarion of acceptor before the try block, like this:

ServerSocket acceptor = null;
try {
    acceptor = new ServerSocket(4782);
} catch (IOException e) {
    System.err.println("ERROR: Couldn't listen on port 4782!");
}
while (true) {
    Socket clientSock = acceptor.accept();
}

For this code, acceptor can be null inside the while-loop, either check for it there or do something flow-alterning inside the catch-block.

You might also want to handle the IOException that Socket clientSock = acceptor.accept(); might throw, since such Exception would break the while-loop - which might not be according to plans.

The general explaination is that java scopes variable declarations "as limiting as possible" acceptor was declared inside the try-block in your code, hence not available/undeclared outside of it.

8 Comments

@climbage That's a rather indirect way of handling it. Best off avoiding the null altogether.
@TomHawtin-tackline indirect is better than not at all. Were I motivated to write an answer myself, I would do it differently.
@climbage But there's no reason to be indirect. I see these sorts of things written incorrect all the time. Typically even after it's corrected it's still wrong. It can easily be written without any confusion.
@TomHawtin-tackline I would argue that checking for null isn't wrong--it just doesn't adhere to your standards of coding. That's fine.
I wouldn't check for null here, I wouldn't initiate acceptor to null either. I would (probably declare acceptor final and) do something flow-altering in the catch block. The question wasn't specifically about this issue, but this issue is very tightly coupled. I wouldn't mind updating my answer some more if I got good suggestions. (My opionion is that checking acceptor for null is "wrong" that scenario should be handled in the catch-block, or maybe maybe in some scenarios in the code catching the NPE.)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.