Re: IllegalArgumentException vs. NullPointerException and collection
behavior
Karsten Wutzke wrote On 08/10/07 10:47,:
Hello!
1. I am wondering for quite some time now:
When passing nulls to my methods and constructors (for required
fields), is it better to use IllegalArgumentException("Blah is null!")
or NullPointerException("Blah is null!")?
Throw NoClassDefFoundError and confuse everybody. ;-)
There's no hard-and-fast rule, but it seems to me more
straightforward to throw IllegalArgumentException (or one
of its subclasses) when an argument fails a validity check.
Sometimes, though, I will let Java do the validity checking
for me, as in
void method(String bass) {
String lower = bass.toLowerCase();
.... instead of
void method(String bass) {
if (bass == null)
throw new IllegalArgumentException(...);
String lower = bass.toLowerCase();
.... in which case the caller will get NPE instead of IAE.
Whatever you do, make sure the Javadoc explains all the
requirements you impose on the argument values: non-nullity,
no zero-length strings, all alphabetic, whatever.
Is there a difference between constructors and methods? What's better
and why?
Not sure what you mean here. Methods and constructors
are different in several ways: Methods may be inheritable
and/or overridable but constructors cannot be, methods can
be called but constructors can only be invoked by `new',
constructors automatically chain to superclass constructors
but no such chaining exists for methods, and so on.
But maybe you mean "Should constructors report failures
of validity checks differently than methods do?" I don't
see any reason to act differently in a constructor: Do the
validation that seems proper, and throw IAE or a subclass
if the tests fail. If a constructor throws an exception
(that isn't caught inside the constructor itself) the object
doesn't get constructed -- but that seems reasonable, since
the parameters describing the new object weren't valid.
2. I'm implementing a list that doesn't allow null elements to be
added:
@Override
public boolean add(E elem)
{
if ( elem == null )
{
throw new NullPointerException("Element is null!");
//throw new IllegalArgumentException("Element is null!");
//return false;
}
return super.add(elem);
}
I can't decide whether to fail silently or to throw an exception.
What's better and why?
If the List's Javadoc says "no nulls," anybody who
tries to add null to it is misusing it: throw an exception.
If the Javadoc says "attempts to add nulls are silently
ignored," just return. You're the class designer; you're
designing the class for a purpose; you make the choice.
By the way, add(E) is not the only way to insert
things into a List<E>: there's aanother flavor of add()
and a couple of flavors of addAll() to worry about, plus
whatever other routes the concrete implementation might
provide (e.g., a constructor that accepts a Collection
that might contain a null or two). If you're building
your own List implementation from the ground up this is
not hard to control, but if you're wrapping some other
List in a "filter" you must make sure no one else can
get a reference to the underlying List that would let
them circumvent your filtration.
--
Eric.Sosman@sun.com