Re: Checking for null parameter
On Jun 11, 4:07 pm, Lew <con...@lewscanon.com.invalid> wrote:
pek wrote:
OK... Let me take you back to what was the meaning of this whole
discussion because I believe that the thing is going out of hand. The
discussion was about CHECKING a null reference, not HANDLING. Here is
an example:
public class ChatExample {
private Connection conn;
public ChatExample() {
// I intentionally forget to instantiate the conn
}
public void connect() throws ConnectionException {
try {
conn.connect();
} catch (ConnectionExcetpion e) {
// Delegate the exception
throw new ConnectionException("Connection failed in Chat",e)=
;
}
}
public sendMessage(String message) throws ConnectionException {
try {
conn.sendMessage(message);
} catch (ConnectionException e) {
// Delegate the exception
throw new ConnectionException("Couldn't send message in
Chat",e);
}
}
class Connection {
public void connect() throws ConnectionException {
// Do socket connection etc. etc.
}
public void sendMessage(String message) throws ConnectionExcepti=
on
{
// Send the message using sockets etc. etc.
}
}
}
public class Main {
public static void Main() {
// Catch and log any exceptions that wheren't planned without
crashing
try {
startProgram();
} catch (NullPointerException e) {
// Log it and inform user
} catch (Exception e) {
// Same here (probably combining with the above exception
wouldn't have any difference
}
}
private void startProgram {
// Do anything
// At some point you want to send a message
ChatExcample chat = new ChatExample();
chat.sendMessage("Hello world");
}
}
OK, now, did you notice that I forgot to instantiate the conn
attribute? That is a bug, which means that the user can NEVER send a
message simply because it is a NPE and it will stay that way no matter
what.
For this sort of thing, use 'assert':
public class ChatExample {
private final Connection conn; // final added
public ChatExample() {
// I intentionally forget to instantiate the conn
assert conn != null;
}
public void connect() throws ConnectionException {
assert conn != null;
try {
conn.connect();
} catch (ConnectionExcetpion e) {
// Delegate the exception
throw new ConnectionException("Connection failed in Chat",=
e);
}
}
public sendMessage(String message) throws ConnectionException {
assert conn != null;
try {
conn.sendMessage(message);
} catch (ConnectionException e) {
// Delegate the exception
throw new ConnectionException("Couldn't send message in
Chat",e);
}
}
We assume some appropriate mechanism for invoking conn.close(), not shown =
here.
Now it is impossible to throw NPE. Problem solved.
As for rethrowing the ConnectionException, that is controversial. At so=
me
point you should recover to correct program state instead of propagating t=
he
exception. Also, in real life of course one would log the ConnectionExc=
eption.
--
Lew
I knew would stick in the coding and don't comment on what is my
point. I totally agree of the recover and stuff. BUT THAT IS NOT MY
POINT! Do better exception handling, do better recover, do anything.
BUT conn WILL STILL THROW A NPE no matter what. Even with the
conn.close(), this code will still throw a NPE. Why wouldn't it? The
attribute conn isn't instantiated, ANY method you call WILL throw a
NPE.
So forget about the way I programmed it (this is an example after
all). The point is that conn is null. And what I am trying to discuss
from the beginning of this thread is that YOU DO NOT HAVE TO CHECK if
it is or not. Not conn, nor any other object passed from a method
EXCEPT if there is meaning to it (if the program will behave in
another matter, and that DOESN'T include handling the NPE).
Am I not making my point clear? Is there any ambiguity in what I'm
saying?
You suggest (from your earlier posts) that the method connect() should
behave like this:
if ( conn == null ) {
handleIt();
} else {
conn.connect();
}
I say DON'T CHECK conn == null. You don't have to because then ALL
YOUR METHODS should check if ANY OBJECT of it's parameter list is
null, which is overkill. If an object reference was null and that
broke your code, it should be found in the testing period of the
program and fixed.
So, once more: I believe that checking for null references anywhere
other than where it makes sense, is overkill. And I'm ONLY talking
about NullPointerExceptions, not any other types of exceptions. Also,
a null reference making sense is when the method still does the job it
suppose to no matter what (I'm thinking Graphics.drawImage where the
image will be drawn even if you pass null to the Observer object).