Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2008

Tip: Looking for answers? Try searching our database.

NullPointerException, IllegalArgumentException, or AssertionError for null constructor argument

Thread view: 
Daniel Pitts - 28 Dec 2007 22:11 GMT
I have a constructor that takes a String argument. I'd like to throw an
exception if the constructor is invoked with a null argument, but I'm
not sure which instruction I should use.
NullPointerException is technically accurate, since it is a null
pointer, but it is also an IllegalArgumentException.  I think that
IllegalArgumentException is more specific, so I'll probably go with
that, but wanted opinions.

The third option is AssertionError.  I could just use assert arg!=null,
and that could be enough.  This is for a personal project, so it doesn't
 *really* matter, but at the same time its good practice for me to
think about these sort of things :-)

Thoughts?

Thanks,
Daniel.
Signature

Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Owen Jacobson - 28 Dec 2007 22:21 GMT
On Dec 28, 2:11 pm, Daniel Pitts
<newsgroup.spamfil...@virtualinfinity.net> wrote:
> I have a constructor that takes a String argument. I'd like to throw an
> exception if the constructor is invoked with a null argument, but I'm
[quoted text clipped - 10 lines]
>
> Thoughts?

Thoughts: private members get assertions if anything at all for
parameter checking (as well as other invariants); public members get
explicit tests if it matters that parameters meet specific
requirements.  I tend to leave NPE to the java runtime to throw and
use IllegalArgumentException for things caught in explicit tests.

Asserts can, after all, be turned off.

Throwing AssertionError explicitly seems like the Wrong Thing. :)
Lew - 29 Dec 2007 03:15 GMT
> On Dec 28, 2:11 pm, Daniel Pitts
> <newsgroup.spamfil...@virtualinfinity.net> wrote:
[quoted text clipped - 22 lines]
>
> Throwing AssertionError explicitly seems like the Wrong Thing. :)

It is.  It is completely contrary to the purpose of the 'assert' mechanism,
and it's an Error, not an Exception.  The 'assert' mechanism is not meant for
runtime checks of data, but for test-time checks of algorithmic correctness.

The great third phase of programming I don't see mentioned much is test-time.
 Everyone talks about compile-time and run-time, but 'assert' is a leader in
test-time functionality.

Again, its purpose is to check the algorithm, not the data.

Signature

Lew

Eric Sosman - 28 Dec 2007 22:38 GMT
> I have a constructor that takes a String argument. I'd like to throw an
> exception if the constructor is invoked with a null argument, but I'm
[quoted text clipped - 8 lines]
>  *really* matter, but at the same time its good practice for me to think
> about these sort of things :-)

    IllegalArgumentException would get my vote, with a possible
last-minute in-the-voting-booth defection to NullPointerException.
AssertionError is the candidate whose placards I'd tear down, no
matter what the election authorities might think.

Signature

Eric Sosman
esosman@ieee-dot-org.invalid

Patricia Shanahan - 28 Dec 2007 22:41 GMT
>> I have a constructor that takes a String argument. I'd like to throw
>> an exception if the constructor is invoked with a null argument, but
[quoted text clipped - 13 lines]
> AssertionError is the candidate whose placards I'd tear down, no
> matter what the election authorities might think.

Agree with this, with the possible addition of a merger between the two
acceptable options - throw an IllegalArgumentException with a
NullPointerException as cause. However, IllegalArgumentException with a
clear message should normally do the job.

Patricia
Arne Vajhøj - 29 Dec 2007 01:26 GMT
> I have a constructor that takes a String argument. I'd like to throw an
> exception if the constructor is invoked with a null argument, but I'm
[quoted text clipped - 3 lines]
> IllegalArgumentException is more specific, so I'll probably go with
> that, but wanted opinions.

IllegalArgumentException

Because

NullPointerException : tells me that the code called
a member on the argument without checking it first

IllegalArgumentException : tells me that code checked
the argument first

and the second one is the correct.

Arne
tzvika.barenholz@gmail.com - 29 Dec 2007 18:20 GMT
On Dec 29, 12:11 am, Daniel Pitts
<newsgroup.spamfil...@virtualinfinity.net> wrote:
> I have a constructor that takes a String argument. I'd like to throw an
> exception if the constructor is invoked with a null argument, but I'm
[quoted text clipped - 15 lines]
> --
> Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

I vote NPE. It's more specific, and basically it's what it's there
fore. IAE could mean any number of things.
Of course if you decide on NPE, you don't actually have to check in
the constructor and explicitly throw NPE - just let it be thrown on
method calls. This is more general, in that it allows construction
with null, then calling setXXX with a legal value, which is useful for
some complex objects.
T
Patricia Shanahan - 29 Dec 2007 18:25 GMT
> On Dec 29, 12:11 am, Daniel Pitts
> <newsgroup.spamfil...@virtualinfinity.net> wrote:
[quoted text clipped - 20 lines]
> I vote NPE. It's more specific, and basically it's what it's there
> fore. IAE could mean any number of things.

IAE means that an argument was invalid, and the Javadoc comments should
give the rules.

Even if the Javadocs indicate that NPE can be caused by a null argument,
short of reading the code, the caller has no way of knowing if the NPE
is due to that, or due to some other problem in the called code. There
are far too many things that cause NPE.

If you are worried about explaining what was wrong with the argument,
you could report the NPE as cause on the IAE. In any case, the message
should be clear.

Patricia
Lew - 29 Dec 2007 18:51 GMT
> Of course if you decide on NPE, you don't actually have to check in
> the constructor and explicitly throw NPE - just let it be thrown on
> method calls. This is more general, in that it allows construction
> with null, then calling setXXX with a legal value, which is useful for
> some complex objects.

Bad advice.

If construction with null is allowed, then it should never throw an NPE,
inside the constructor or passed through to the caller.  If you need special
handling for null, use
  if ( foo == null )
not an NPE, to check for it.

Certainly the constructor shouldn't pass through any exceptions without a
logging discipline.  (Nor should any method.)

Checked exceptions are a good way to ensure that client code will handle the
exception thrown by a constructor or method.

Signature

Lew

tzvika.barenholz@gmail.com - 30 Dec 2007 09:15 GMT
> tzvika.barenh...@gmail.com wrote:
> > Of course if you decide on NPE, you don't actually have to check in
[quoted text clipped - 19 lines]
> --
> Lew

On second thought, when construction with null is allowed, then
subsequent method calls *could* reasonably throw IllegalStateException
if the object is still null when they need them. Still, I like to call
a spade a spade, so when something fails because a pointer is null, it
makes sense to let NPE be thrown.

As for your objection to non-checked exception here, it is valid of
course. But most java programmers will probably frown at having to try-
catch around a method call just for the case that the object reference
they pass is null, when they know for a fact it isn't.

T
Lew - 30 Dec 2007 15:47 GMT
> On second thought, when construction with null is allowed, then
> subsequent method calls *could* reasonably throw IllegalStateException
> if the object is still null when they need them. Still, I like to call
> a spade a spade, so when something fails because a pointer is null, it
> makes sense to let NPE be thrown.

Lew wrote:
>> Checked exceptions are a good way to ensure that client code will handle the
>> exception thrown by a constructor or method.

> As for your objection to non-checked exception here, it is valid of course.

Rrr?

How do you derive an "objection" to unchecked exceptions, much less attribute
such to me?

Such an objection most emphatically is not valid.  Of course.

> But most java [sic] programmers will probably frown at having to try-
> catch around a method call just for the case that the object reference
> they pass is null, when they know for a fact it isn't.

Most Java programmers are very junior in their craft.  Anyway, checked
exceptions are for when you don't "know for a fact it isn't"; unchecked
exceptions are for when you should have known better.  Checked exceptions are
more for runtime conditions that the API insists that the client handle.
Unchecked exceptions are for programming mistakes, mostly.  Errors are just to
let you log some desperate cry for maintenance before crashing.

It is up to the API designer to design the API.  Part of a method's design,
arguably the most important part, is its method signature.  If it is important
for a client of the method to handle an exception, Java provides the checked
exception as the way for the API designer to ensure it.  The irritation of
lazy, unenlightened programmers is not a consideration.

If a designer is too lax or too strict in their design, that is a designer's
error.  Designers are responsible for their errors, and indeed some of the
best APIs have design flaws.  For example, java.util.Date.

For an API designer to avoid designing checked exceptions is bad, bad.  With
every method you design you have a choice - throw no exceptions, throw one or
more unchecked exceptions, throw one or more checked exceptions, or a
combination of the latter two.  (There isn't much need to design Error into
the signature.  If I think I need to design an Error, I'm going to rethink the
situation.)

Your choice is determined by your intention for the API.  What invariants must
you maintain?  Must a client deal with exceptions, as, say, for IOExceptions
thrown by a Stream?  You certainly want to ensure that clients are aware of
the likelihood of an exception, and guarantee that they have code in place to
deal with it.  Could there be more than one exceptional condition so different
that they need different Exception types?  See Class.newInstance().  Might the
problem be actually uncatchable, but still so important that it belongs in the
signature?  That's an Error, folks, as from Class.forName().

Notice that checked exceptions are mostly responses to run-time conditions -
they do not represent programmer mistakes.  Unchecked exceptions tend to
happen for things the programmer can control, like whether a variable is null.
   (Assertions are to check algorithmic invariants.)

Some exceptions are fundamental and essentially controllable by the client
programmer.  Invoking 'new Integer("Snark")' or 'Integer.valueOf("Snark")'
throws a RuntimeException, to be caught by the programmer that they may fix
their own mistake.  Integer really should not throw a checked exception here.

Be careful about reading into people's comments things that not only they did
not say, but with which they disagree.

Signature

Lew

Mark Rafn - 29 Dec 2007 22:23 GMT
>On Dec 29, 12:11 am, Daniel Pitts
>> I have a constructor that takes a String argument. I'd like to throw an
>> exception if the constructor is invoked with a null argument
...

>I vote NPE.  It's more specific, and basically it's what it's there

I vote IllegalArgumentException.  NPE implies a bug or unexpected state inside
the code, where IAE makes it clear that the bug is in the code making the
call.

AssertionError is right out.  Assertions exist to make low-severity bugs into
high-severity ones so you can find and fix them.  They're not part of an API
design.
--
Mark Rafn    dagon@dagon.net    <http://www.dagon.net/>
Lew - 29 Dec 2007 23:38 GMT
> AssertionError is right out.  Assertions exist to make low-severity bugs into
> high-severity ones so you can find and fix them.  They're not part of an API
> design.

I agree with your conclusion, but quibble over a detail.  Assertions do not
"exist to make low-severity bugs into high-severity ones" at all.  They exist
to verify pre- and post-conditions to ensure algorithmic correctness.  The
bugs, if any, that are thus discovered will have been "high-severity" bugs all
along.  Assertions exist to make such high-severity issues visible to testers
and developers before they are visible to customers.  Assertions usually are
and generally should be disabled in production, very much unlike exceptions.

The difference between exceptions and assertions is that they test for
different things at different points in the application lifecycle.  Exceptions
handle anomalous data and like conditions at run-time.  Assertions handle
incorrect algorithms at test-time.

Signature

Lew

John W. Kennedy - 30 Dec 2007 04:57 GMT
>> AssertionError is right out.  Assertions exist to make low-severity
>> bugs into
[quoted text clipped - 15 lines]
> Exceptions handle anomalous data and like conditions at run-time.  
> Assertions handle incorrect algorithms at test-time.

Remember how people used to complain about parity-checked ROM?

Signature

John W. Kennedy
A proud member of the reality-based community.

Lew - 30 Dec 2007 05:01 GMT
>>> AssertionError is right out.  Assertions exist to make low-severity
>>> bugs into
[quoted text clipped - 17 lines]
>
> Remember how people used to complain about parity-checked ROM?

Please refresh our collective memories on this matter.  I for one am quite
interested.  Why did people complain about parity-checked ROM?  Do they still,
and if not, why not?

A few words of how that ties in might not be remiss.

Signature

Lew

John W. Kennedy - 30 Dec 2007 23:33 GMT
>>>> AssertionError is right out.  Assertions exist to make low-severity
>>>> bugs into
[quoted text clipped - 23 lines]
>
> A few words of how that ties in might not be remiss.

Whoops! That should have been "RAM".

Signature

John W. Kennedy
Read the remains of Shakespeare's lost play, now annotated!
http://pws.prserv.net/jwkennedy/Double%20Falshood/index.html

Lew - 31 Dec 2007 03:06 GMT
>>> Remember how people used to complain about parity-checked ROM?

Lew wrote:
>> Please refresh our collective memories on this matter.  I for one am
>> quite interested.  Why did people complain about parity-checked ROM?  
>> Do they still, and if not, why not?
>>
>> A few words of how that ties in might not be remiss.

> Whoops! That should have been "RAM".

Please refresh our collective memories on this matter.  I for one am quite
interested.  Why did people complain about parity-checked RAM?  Do they still,
and if not, why not?

A few words of how that ties in might not be remiss.

Signature

Lew

Patricia Shanahan - 31 Dec 2007 03:13 GMT
>>>> Remember how people used to complain about parity-checked ROM?
>
[quoted text clipped - 12 lines]
>
> A few words of how that ties in might not be remiss.

The problem with parity, as distinct from ECC, is that all you can do if
it detects an error is abort anything that is affected by the location
showing the error. However, arguably that is better than not having any
error detection. In most cases, a wrong answer is worse than an abort.

Patricia
John W. Kennedy - 31 Dec 2007 05:25 GMT
>>>> Remember how people used to complain about parity-checked ROM?
>
[quoted text clipped - 12 lines]
>
> A few words of how that ties in might not be remiss.

Weren't you on-line in the mid-80s? "I don't want this dumb parity
checking; it makes my system crash," was even more popular than, "My
computer must be broken, because 1/3 + 1/3 + 1/3 is coming out 0.999999
instead of 1.0."

Signature

John W. Kennedy
"There are those who argue that everything breaks even in this old dump
of a world of ours. I suppose these ginks who argue that way hold that
because the rich man gets ice in the summer and the poor man gets it in
the winter things are breaking even for both. Maybe so, but I'll swear I
can't see it that way."
  -- The last words of Bat Masterson

Mark Rafn - 30 Dec 2007 07:27 GMT
>> AssertionError is right out.  Assertions exist to make low-severity bugs into
>> high-severity ones so you can find and fix them.  They're not part of an API
>> design.

>I agree with your conclusion, but quibble over a detail.  Assertions do not
>"exist to make low-severity bugs into high-severity ones" at all.

I was being glib, but there is some truth behind my statement.  The reason to
have assertions in code (as opposed to just comments, or non-assertion
conditions that throw exceptions, is to ensure that a mismatch between the
developer's expectations and reality causes an event that's very hard to
miss.

>They exist to verify pre- and post-conditions to ensure algorithmic
>correctness.  The bugs, if any, that are thus discovered will have been
>"high-severity" bugs all along.

Yes.  It might be clearer to say that assertions turn logic bugs into crash
bugs.  That crash bugs are higher severity than more subtle misbehavior is
not universal.

>The difference between exceptions and assertions is that they test for
>different things at different points in the application lifecycle.  Exceptions
>handle anomalous data and like conditions at run-time.  Assertions handle
>incorrect algorithms at test-time.

Agreed.
--
Mark Rafn    dagon@dagon.net    <http://www.dagon.net/>
Lew - 30 Dec 2007 17:04 GMT
Lew wrote:
>> I agree with your conclusion, but quibble over a detail.  Assertions do not
>> "exist to make low-severity bugs into high-severity ones" at all.

> I was being glib, but there is some truth behind my statement.  The reason to
> have assertions in code (as opposed to just comments, or non-assertion
> conditions that throw exceptions, is to ensure that a mismatch between the
> developer's expectations and reality causes an event that's very hard to
> miss.

Specifically, expectations and reality in the domain of algorithmic invariants
and like issues.  Contrast to exceptions, that expose such a mismatch in the
domain of data correctness or environmental conditions.

> It might be clearer to say that assertions turn logic bugs into crash bugs.  

Contrast to exceptions, that turn data or environment bugs into recoverable bugs.

> That crash bugs are higher severity than more subtle misbehavior is not universal.

I'm not sure that seeing "DangerDangerException ... [stack trace]" on a user's
screen is subtle misbehavior.  Maybe compared to having a klaxon go off in
conjunction?

Assertions turn crash bugs into logged, analyzable crash bugs, and they do it
before you go into production.

If I translate "severity" into "visibility" I agree with your characterization
of assertions.  I was using a different definition of "severity".

The quibble has vanished in the bright light of agreement.

Signature

Lew

Zig - 30 Dec 2007 04:25 GMT
> I have a constructor that takes a String argument. I'd like to throw an  
> exception if the constructor is invoked with a null argument, but I'm  
[quoted text clipped - 3 lines]
> IllegalArgumentException is more specific, so I'll probably go with  
> that, but wanted opinions.

There's been some good advice from other posters here, but I thought I'd  
throw in a couple observations.

From java.lang.NullPointerException:

"Thrown when an application attempts to use null in a case where an object  
is required. These include:
...
Applications should throw instances of this class to indicate other  
illegal uses of the null object."

Next, we know that a constructor is a special kind of method, so let's  
assume that the convention for checking arguments on a method is the same  
as the convention for checking arguments on a constructor. With a little  
bit of poking around, we see methods like java.lang.Enum.valueOf

Throws:
    IllegalArgumentException - if the specified enum type has no constant  
with the specified name, or the specified class object does not represent  
an enum type
    NullPointerException - if enumType or name is null

If you also want to see a constructor: java.lang.StringBuilder(String)

Throws:
    NullPointerException - if str is null

Given that, it appears that Sun's convention is to throw a NPE whenever a  
null is found where it shouldn't be. IllegalArgumentException seems to be  
better suited in cases where the arguments can only be within a subset of  
the values allowed by type of the argument.

As this would seem to be a matter of convention, I've cited Sun's, but  
Sun's is not the only convention. SWT programmers seem to like using

throw new SWTException(SWT.ERROR_NULL_ARGUMENT);
    or
throw new SWTException(SWT.ERROR_INVALID_ARGUMENT);
    or even
throw new SWTException(SWT.ERROR_CANNOT_BE_ZERO);
etc.

HTH,

-Zig
Lew - 30 Dec 2007 04:59 GMT
> Next, we know that a constructor is a special kind of method,

There are many important differences between a constructor and a method, of
sufficient magnitude that it is more useful to think of constructors not being
methods at all.

They do, however, share the ability to receive parameters and throw exceptions
with methods. Zig's main point about argument checking is therefore completely
applicable, of course.

With respect to the rest of those points, let me warn that Sun's libraries are
not free of unfortunate choices.  They may not always represent current best
practices.

The choice of NPE or IllegalArgumentException is the classic Java angel's ball
[1] on the head of a pin.  You should use NPE when you decide that users of
your library should be primarily aware of the nullness of the argument.  You
should use IllegalArgumentException when you decide that users of your class
should be primarily aware of its illegality.  You use the latter with the
former as a cause when you decide that users should be primarily aware of the
illegality and that it's illegal on account of nullness.  The driver of your
choice is your what you will for client classes to experience.

Personally, I choose the third, combination option for clients of my code
pretty much always, because pretty much always it's the nature of the argument
as an argument that's important for the client class to track, and whether
it's legal is the first consideration, why it's illegal the second.

[1] ball in the sense of a formal dance.

Signature

Lew

Roedy Green - 31 Dec 2007 03:52 GMT
On Fri, 28 Dec 2007 14:11:42 -0800, Daniel Pitts
<newsgroup.spamfilter@virtualinfinity.net> wrote, quoted or indirectly
quoted someone who said :

>IllegalArgumentException.

that is what Sun tends to use for anything wrong with parms.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Lew - 04 Jan 2008 04:58 GMT
> I have a constructor that takes a String argument. I'd like to throw an
> exception if the constructor is invoked with a null argument, but I'm
[quoted text clipped - 10 lines]
>
> Thoughts?

Here's an example of the difference between assertion and exception
generation.  The assertion is forced to hold by the exception handling.  If
the exception-handling algorithm were wrong, the null could perhaps slip
through, and the assert would fail.  This should never happen.

The assert is there to alert us if the exception failed to do its job.  The
programmer is asserting that the exception clause is sufficient.

public class NoNullHolder <T>
{
 private final T held;

 public NoNullHolder( T toHold )
 {
   if ( toHold == null )
   {
     throw new IllegalArgumentException( new NullPointerException(
        "null toHold" ));
   }
   held = toHold;
   assert held != null; // postcondition invariant
 }

 public final T getHeld()
 {
   assert held != null; // precondition invariant
   return held;
 }
}

Signature

Lew



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.