advice needed on checking for null object references

M

marlow.andrew

I am mainly a C++ programmer currently moving more and more into java.
So when I look at java code I tend to do so with a C++ hat on.So
please bear that in mind as you consider this question: Is it normal
for (java) methods to check an object reference for null before using
it?

In C++ the equivalent idea is checking an input pointer for null
before using it. For C++ it is normal to do this and throw an
application-specific exception if the pointer is null. The check is to
do with ensuring class invariants and is particularly useful in the
constructor. In C++ it is disastrous not to do the check, since the
entire executable explodes into tiny fragments when you reference
through a null pointer. Of course, java is more forgiving and throws a
NPE. I guess this is why java code tends not to make the check. If a
class invariant is violated this indicates a coding error and under
those conditions you do want a full diagnostic trace to tell you where
the invariant is violated. The C++ solution gives this to you but only
if you are a diligent coder. In java you don't have to write any code
but you don't quite get the full solution. You only get told where the
code blew up, not where the class invariant was first violated.

Regards,

Andrew Marlow
 
M

Mark Space

through a null pointer. Of course, java is more forgiving and throws a
NPE. I guess this is why java code tends not to make the check. If a


I'm of two minds on this. All of the following is just personal
opinion. First, checking all parameters on public methods is good, and
generally programmers should do this. Throwing specific error messages
rather than generic ones is also preferred.

However, as you point out, the behavior of Java is pretty benign when a
null reference is used. So it might make sense to use the default
behavior. OTOH, you made a comment about "where the class invariant was
first violated," so I feel some more discussion is in order.

If you have a class like this:

public class Example {
Object obj; // must not be null!
public Example( Object obj ) {
if( obj == null ) {
throw new NullPointerException("Object was null.");
}
this.obj = obj;
}
//...
}

Then yes, you really should check for null. As you say the place where
the class invariant was violated is too far from where the error will be
found.

One thing I did not show above was the javadoc. You must document when
any method throws NPE. And you must document the invariant that obj
must not be null.

A slightly different case, something like this fragment is fine imo:

/** Validates input string. Throws NPE if s is null. */
public boolean validate( String s ) {
// make sure it's not more than 80 characters long
if( s.length() > 80 ) {
return false;
}
return true;
}

This fragment does not contain an explicit check for null but documents
the NPE and uses the default Java behavior for throwing NPE. This is
fine. It might be better to check for null and return false, but it
might not. Depends on the design.

The second example illustrates I think where checking for null and
throwing NPE is optional. The first example, checking for null is not
really optional. If obj being not null is a class invariant, then not
checking for it is just sloppy coding, imo.
 
L

lord.zoltar

I am mainly a C++ programmer currently moving more and more into java.
So when I look at java code I tend to do so with a C++ hat on.So
please bear that in mind as you consider this question: Is it normal
for (java) methods to check an object reference for null before using
it?

In C++ the equivalent idea is checking an input pointer for null
before using it. For C++ it is normal to do this and throw an
application-specific exception if the pointer is null. The check is to
do with ensuring class invariants and is particularly useful in the
constructor. In C++ it is disastrous not to do the check, since the
entire executable explodes into tiny fragments when you reference
through a null pointer. Of course, java is more forgiving and throws a
NPE. I guess this is why java code tends not to make the check. If a
class invariant is violated this indicates a coding error and under
those conditions you do want a full diagnostic trace to tell you where
the invariant is violated. The C++ solution gives this to you but only
if you are a diligent coder. In java you don't have to write any code
but you don't quite get the full solution. You only get told where the
code blew up, not where the class invariant was first violated.

Regards,

Andrew Marlow

In some cases, you may not care if your code tries to reference a null
object. You might be perfectly content to let the NPE get thrown and
have the error and stack trace dumped to a log that someone will read
in a few days when a user mentions some generic "weird problem [they]
had yesterday, or was it the day before?". There are cases where the
system can recover and perform "good enough" even with NPE's getting
thrown now and then.
And in other cases, you will want to explicitly check for null before
attempting any further processing.
Even though it's not always essential (it will depend on your
application's domain), I'd still say the better way is to check (and
handle) whenever possible.
 
L

Lew

Mark said:
... you made a comment about "where the class invariant was
first violated," so I feel some more discussion is in order.

If you have a class like this:

public class Example {
   Object obj; // must not be null!
   public Example( Object obj ) {
     if( obj == null ) {
       throw new NullPointerException("Object was null.");
     }
     this.obj = obj;
   }
   //...

}

Then yes, you really should check for null.  As you say the place where
the class invariant was violated is too far from where the error will be
found.
...
One thing I did not show above was the javadoc.  You must document when
any method throws NPE.  And you must document the invariant that obj
must not be null.

...  [In t]he first example, checking for null is not
really optional.  If obj being not null is a class invariant, then not
checking for it is just sloppy coding, imo.

Here is where 'assert' comes in. The Java 'assert' mechanism is
designed for invariants. The constructor in Mark Space's example
should have an 'assert' at the location where the invariant was first
established. Subsequent 'get()' methods should 'assert' the
precondition invariant also.

In this version of the example, the attribute is 'final', and I'll use
type 'Foo' instead of 'Object'.

/** Example to show use of exceptions backed by assertions to prove
invariants. */
public class Example
{
/** Attribute which must not be null. */
private final Foo foo;

/** Constructor.
* Ensures that element <code>foo</code> is not null.
* @param foo foo value to which to set attribute, cannot be
<code>null</code>.
* @throws NullPointerException if <code>foo == null</code>.
*/
public Example( Foo foo )
{
if( foo == null )
{
throw new NullPointerException( "Foo was null." );
// IllegalArgumentException also a good choice
}
this.foo = foo;

assert this.foo != null;
}

/** Get the <code>foo</code> attribute.
* @return Foo attribute value, guaranteed not <code>null</code>.
*/
public Foo getFoo()
{
assert this.foo != null;
return this.foo;
}
}
 
M

marlow.andrew

Here is where 'assert' comes in.  The Java 'assert' mechanism is
designed for invariants.  

Thanks for reminding me of this java feature. I had completely
forgotten. Perhaps in part that it because it doesn't seem to be used
very much. No one on my project has ever mentioned it, including all
the architects.
The constructor in Mark Space's example
should have an 'assert' at the location where the invariant was first
established.  

Hmm. The example shows an exception being used initially, then assert
being used at the point where the invariant is assumed to hold (i.e.
to check that it really does hold!).
Subsequent 'get()' methods should 'assert' the
precondition invariant also.
Indeed.

 /** Example to show use of exceptions backed by assertions to prove
invariants. */
 public class Example
 {
  /** Attribute which must not be null. */
  private final Foo foo;

  /** Constructor.
   * Ensures that element <code>foo</code> is not null.
   * @param foo foo value to which to set attribute, cannot be
<code>null</code>.
   * @throws NullPointerException if <code>foo == null</code>.
   */
  public Example( Foo foo )
  {
    if( foo == null )
    {
      throw new NullPointerException( "Foo was null." );
      // IllegalArgumentException also a good choice
    }
    this.foo = foo;

[ rest of code snipped including assert statement ]

This is just the job exception for one small thing. Assertions are
disabled by default. They have to be consciously turned on and it is
very easy to forget. See http://thesoftwarelife.blogspot.com/2008/05/dont-forget-to-enable-java-assert.html.

Regards,

Andrew Marlow
 
G

Giovanni Azua

Mark Space said:
if( obj == null ) {
throw new NullPointerException("Object was null.");
}
You could also use the nicer and syntactic sugar variation offered by Apache
commons lang http://commons.apache.org/lang/ that achieves the same thing:

import org.apache.commons.lang.Validate;
....

Validate.notNull(obj, "'obj' must not be null");

Best regards,
Giovanni
 
L

Lew

This is just the job exception for one small thing. Assertions are
disabled by default. They have to be consciously turned on and it is
very easy to forget. See  http://thesoftwarelife.blogspam.com/2008/05/dont-forget-to-enable-jav....

Assertions should be off in production. They only get turned on in
production when someone suspects an invariant violation.

Assertions are not exceptions. They work differently and they serve
different purposes. Exceptions enforce invariants; assertions prove
them.

Leaving assertions on in production is just requiring proof for the
same thing over and over. Once you are confident in development that
your exceptions and other logic enforce the invariants, you turn the
assertions off.

The normal state for assertions is off.
 
A

Arved Sandstrom

I am mainly a C++ programmer currently moving more and more into java.
So when I look at java code I tend to do so with a C++ hat on.So
please bear that in mind as you consider this question: Is it normal
for (java) methods to check an object reference for null before using
it?

In C++ the equivalent idea is checking an input pointer for null
before using it. For C++ it is normal to do this and throw an
application-specific exception if the pointer is null. The check is to
do with ensuring class invariants and is particularly useful in the
constructor. In C++ it is disastrous not to do the check, since the
entire executable explodes into tiny fragments when you reference
through a null pointer. Of course, java is more forgiving and throws a
NPE. I guess this is why java code tends not to make the check. If a
class invariant is violated this indicates a coding error and under
those conditions you do want a full diagnostic trace to tell you where
the invariant is violated. The C++ solution gives this to you but only
if you are a diligent coder. In java you don't have to write any code
but you don't quite get the full solution. You only get told where the
code blew up, not where the class invariant was first violated.

Regards,

Andrew Marlow

In Java code I end up checking for null frequently. This has largely to
do with the environment that I program in most of the time: J2EE. In
many situations null is a legitimate value for an object reference -
after all, it merely means that no object is referred to. It's not a
mistake.

In these situations an object reference with a value of null is no more
an error than a database field being null.

Often then, when execution comes back to a variable and it's null again,
it's senseless to throw an NPE. There is no error. The sensible thing to
do is check for null, and do actual logic (sometimes re-initialization)
if the reference is null.

In situations where a reference ought never to be null, I don't check
it. As Lew suggested, at testing time I might use assertions. In any
case, at production time, if I haven't discovered all of these, I (or
some maintenance programmer) will deal with the NPEs in the log files.

AHS
 
J

Joshua Cranmer

Is it normal
for (java) methods to check an object reference for null before using
it?

Quite normal. There are many times, as in C++, where null is a valid
value. Many of Java's collections in java.util are null-safe, for example.
 
D

Daniel Pitts

I am mainly a C++ programmer currently moving more and more into java.
So when I look at java code I tend to do so with a C++ hat on.So
please bear that in mind as you consider this question: Is it normal
for (java) methods to check an object reference for null before using
it?

In C++ the equivalent idea is checking an input pointer for null
before using it. For C++ it is normal to do this and throw an
application-specific exception if the pointer is null. The check is to
do with ensuring class invariants and is particularly useful in the
constructor. In C++ it is disastrous not to do the check, since the
entire executable explodes into tiny fragments when you reference
through a null pointer. Of course, java is more forgiving and throws a
NPE. I guess this is why java code tends not to make the check. If a
class invariant is violated this indicates a coding error and under
those conditions you do want a full diagnostic trace to tell you where
the invariant is violated. The C++ solution gives this to you but only
if you are a diligent coder. In java you don't have to write any code
but you don't quite get the full solution. You only get told where the
code blew up, not where the class invariant was first violated.
The trouble is that in Java, *every* non-numeric variable is a pointer,
so you would always have to check every reference. While this may not
be a bad practice, it becomes unwieldy very quickly.

Best practices say you should throw an NPE, IllegalArgumentException, or
IllegalStateException as soon as you become aware of the broken
invariant, as close as possible to the point where client code breaks
the invariant.

This doesn't always happen, but if you are writing code, and feel like
being extra well behaved, that is the approach to take.
 
R

Roedy Green

Is it normal
for (java) methods to check an object reference for null before using
it?

Java is going to check it for you anyway. So you can count on stack
dump and termination.

I find Java's sloppy distinctions between null and empty needs some
work. See http://mindprod.com/jgloss/empty.html

You do check with methods that have optional parms, with the unused
ones marked with null.

There is not too much point in

assert x != null : "x null";

since that will happen anyway.
--
Roedy Green Canadian Mind Products
http://mindprod.com

Never discourage anyone... who continually makes progress, no matter how slow.
~ Plato 428 BC died: 348 BC at age: 80
 
L

Lew

Thanks for reminding me of this java feature. I had completely
forgotten. Perhaps in part that it because it doesn't seem to be used
very much. No one on my project has ever mentioned it, including all
the architects.

Then they should wake up and start using it!

Used properly, 'assert' is tremendously useful.

Hmm. The example shows an exception being used initially, then assert
being used at the point where the invariant is assumed to hold (i.e.
to check that it really does hold!).

Yep.
 
A

Andrew

Quite normal. There are many times, as in C++, where null is a valid
value. Many of Java's collections in java.util are null-safe, for example.

But that's not what I was talking about. I am talking about classes
where it is an error for the private data member to be null. It is an
error because methods in the class will invoke methods on that object.
Obviously you will get an NPE if you try to do that with a null object
reference.

-Andrew Marlow
 
C

charlesbos73

Hi,

the guys at JetBrains (authors of the IntelliJ IDEA Java IDE)
use the @NotNull and @Nullable annotations everywhere in their
code.

IDEA checks *in real-time* and warns you if some @NotNull annotated
field can possibly receive a null value, which is very convenient.

It's not about waiting for the code to blow up on a failing assertion:
it's about getting the IDE telling you *immediately* that there's a
potential problem.

It's not exactly like it's new: we're using these @NotNull
and @Nullable construct in our code since literally years
while there are still people struggling with NPEs and failing
assertions.

A case could be made that everything should be @NotNull by default
and that "nullable" thinggies should be annotated as "@Nullable",
just like with "final", but this view is unlikely to be regarded
as interesting in this newsgroup (where JLS-nazis regard everything
present in the Java language as uncriticizable holy gospel).

Before deciding on what to use I'd take a look at
the most impressive Java apps out there: IntelliJ IDEA
appears to be the most succesful and the most impressive
Swing app ever written, so these guys cannot be completely
wrong ;)
 
T

Tom Anderson

A case could be made that everything should be @NotNull by default and
that "nullable" thinggies should be annotated as "@Nullable",

Not just a case, but an unarguably correct case. Null is a value which is
occasionally useful, and usually painful, so anything which keeps it
tightly controlled is good news.

Tony Hoare invented null, and regrets it:

http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake

I want syntax like this:

String a = "foo";
String? b = null;
b = a; // okay
a = b; // compile time error
just like with "final", but this view is unlikely to be regarded as
interesting in this newsgroup (where JLS-nazis regard everything present
in the Java language as uncriticizable holy gospel).

Oh, you really are a prick. No offence, but get over yourself.

tom
 
A

Arved Sandstrom

Andrew said:
But that's not what I was talking about. I am talking about classes
where it is an error for the private data member to be null. It is an
error because methods in the class will invoke methods on that object.
Obviously you will get an NPE if you try to do that with a null object
reference.

-Andrew Marlow

It's up to you to initialize an object reference. It may be done in the
constructor, or it may be the case that methods using that object
reference expect it to be null from time to time, in which case a getter
that performs lazy initialization is a common idiom.

This may be sophistry, but it's not so much the object reference being
null that is the error, but your attempt to _use_ it when it's null.
You're the programmer - it's up to you to know when and where that
reference should not be null, in which case there's no point in checking
it, or when it could be, in which case you should.

An NPE that happens to me means one thing: I used an object reference at
a specific point and I believed mistakenly that it could never be null
there.

AHS
 
A

Arved Sandstrom

Tom said:
Not just a case, but an unarguably correct case. Null is a value which
is occasionally useful, and usually painful, so anything which keeps it
tightly controlled is good news.
[ SNIP ]

I deal with Java object references in JSF managed beans and in JPA.
Believe you me, I like null. In that environment it's frequently the
case that a reference must be undefined, because there is no default
value that makes sense and currently the variable points at nothing.
Hence null.

If I had to use these annotations I would have @Nullables all over the
place.

I do agree that there are some situations where one can identify object
references that should never be null, in which case an ability to
declare non-nullable variables is useful. This is actually what CAR
Hoare said, not that nullable references should be turfed.

I'm cool with your proposed syntax. It's what C# has after all, and it's
concise and mnemonic.

AHS
 
A

Arne Vajhøj

charlesbos73 said:
A case could be made that everything should be @NotNull by default
and that "nullable" thinggies should be annotated as "@Nullable",
just like with "final", but this view is unlikely to be regarded
as interesting in this newsgroup (where JLS-nazis regard everything
present in the Java language as uncriticizable holy gospel).

I think you are correct that such a change will not be considered
particular interesting by people here.

It is because there are some people here with programming
experience. They know how much it would cost to fix existing
code that will break with such a change.
Before deciding on what to use I'd take a look at
the most impressive Java apps out there: IntelliJ IDEA
appears to be the most succesful and the most impressive
Swing app ever written, so these guys cannot be completely
wrong ;)

Given that it is not even the most widely used Java IDE written
in Swing, then I would not call it the most successful.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top