public Neocortex(Region rootRegion, ConnectionInterface functor) {
this.rootRegion = rootRegion;
this.currentRegion = this.rootRegion;
this.functor = functor;
}
Hey above I have the constructor for one of my classes. My question is should I add null pointer exceptions to the constructor or would this be unnecessary? Honestly, I just don't understand when I should add exceptions to my code. But in this case which constructor should i use?
public Neocortex(Region rootRegion, ConnectionInterface functor) {
if (rootRegion == null) {
throw new NullPointerException("rootRegion cannot be null");
} else if (functor == null) {
throw new NullPointerException("functor cannot be null");
}
this.rootRegion = rootRegion;
this.currentRegion = this.rootRegion;
this.functor = functor;
}
Well... It is a matter of taste.
If the preconconditions for the class is that rootRegion has to be provided, it makes sense to protect the class implementation from the need to make null checks all over the place.
So to answer the question "When should I throw exception in a constructor" : I would do it in all cases where the parameters, from the consumer, brings your implementation in a invalid state, delegate the problem (ie. throw the exception).
If you try to take the role as consumer for a while, and you choose not to make the null-checks he will have code like:
Neocortex n = new Neocortex(null,null);
n.doSomeething();
If he reach the 2nd line, and the implementation here throws a NullPointerException it will not be clear for him that it is due to the parameters he provided.
I would throw an IllegalArgumentException for those arguments to the constructor that, if accepted, would lead to something bad (including, but not limited to, a null argument). That is, it would lead to the completed construction of an object that doesn't make sense.
Don't throw a NullPointerException, because you haven't attempted to call a method on something null yet.
From the IllegalArgumentException javadocs:
Thrown to indicate that a method has been passed an illegal or inappropriate argument.
And if null is inappropriate, then throw an IllegalArgumentException.
Yes, if null is not an acceptable value for rootRegion, etc., then throw NullPointerException from the constructor. From the NullPointerException documentation, where it talks about when the JVM will throw this, but also says:
Applications should throw instances of this class to indicate other illegal uses of the null object.
You could use IllegalArgumentException for the more general case of arguments that aren't valid for the constructor, but NullPointerException is exactly right for the case of an argument being null that ought not be. IllegalArgumentException does have the advantage, though, of being pretty darned clear about what's wrong. :-)
In this specific case I'd throw an IllegalArgumentException, which means a lot more to the user of your class than a NullPointerException.
It is not a bad practice to have constructors throw exceptions. However, you should make sure that they are well documented (especially in the case of runtime exceptions), and meaningful to the caller.
Related
I had a reason to go into the source code for Throwable.getCause today and was a little surprised to see this code in that method:
public synchronized Throwable getCause() {
return (cause==this ? null : cause);
}
This is from Java 1.8, but it looks the same in the later versions I've looked at.
My question is: why not simply return cause and be done with it?
The code:
public synchronized Throwable getCause() {
return (cause==this ? null : cause);
}
Says if the cause is this return null otherwise return cause (which may also be null as it happens.
The story starts with this: private Throwable cause = this; which is I believe the same in all versions >=1.4. That initialises the cause to being this object!
The intention is that Throwable objects are immutable but it provides a method void initCause(Throwable cause) that can only be called once to initialise the cause or cause initialised by a constructor.
As the documentation explains that allows the chaining of causes to sub-classes added before cause was introduced that don't include it in one of their constructors.
So the class somehow wants to know if initCause has been called and throws IllegalStateException if it has (my comments):
public Throwable initCause(Throwable cause) {
if (cause == this) //Illogical! An exception can't be self caused!
throw new IllegalArgumentException();
if (this.cause != this)// false if cause has been initialised 'properly'.
throw new IllegalStateException();
this.cause = cause;
return this;
}
The class is using cause==this to indicate cause not set.
It can't use cause==null because null is a valid value. So it uses the anomalous state of cause==this because actively setting cause to this is the illogical state of a self-caused exception.
It works, sure. But is it really a good idea?
I'm saying not. It conflates the states of "cause not set" and "cause has been set and is set to null".
A less contorted design just introduces a flag private boolean isCauseSet=false; and setting it if initCause is ever called or a constructor that sets it is called.
The convoluted code we see in Throwable achieves nothing more than avoiding a boolean.
Saving a single boolean field inside Throwable really doesn't seem worth the bother.
No useful application will ever have so many Throwable objects in circulation for it to matter.
It isn't comparing cause to null, it's comparing cause to this. To avoid circles, if cause is this, it returns null.
This null value is used by printStackTrace method e.g. when calling stackTraceString method, lines 421..450 to identify when the output of the stack trace should be finished.
I have public method add(String) that calls private method inspectSequence(String) to check whether String valid or not.
This method returns array if passed String is valid, if it's invalid then method throws IllegalArgumentException
the code is next
public void add(String sequence) throws IllegalArgumentException{
inspectSequence(sequence);
}
private int[] inspectSequence(String sequence){
int[] array;
//some actions
if(<some condition>) throw new IllegalArgumentException("description");
return array;
}
So in cases, when invalid String were passed to add method output will be next:
java.lang.IllegalArgumentException: description
at inspectSequence
at add
But I don't want user to know about private inspectSequence method because this is realization detail, right?
So what I can do in that case? Is it a good idea to throw unchecked exception here?
And is a good idea to throw exception inside inspectSequence method or I should return null when supplied String isn't valid and then check returned result in add method and depending on it throw or not throw exception?
But I don't want user to know about private inspectSequence method because this is realization detail, right?
I'd say no. It's true that you don't want the user (which in that context means someone calling the code) to "know" about internal methods like inspectSequence(). With "know" I mean be able to call, depend upon etc.
Knowing that the exception might be thrown and under what circumstances is something that a caller should know about, knowing where exactly it is thrown isn't necessary but wouldn't hurt.
Of course you could catch that exception in the calling method and throw another one but that would just lose information and might make the code harder to debug/maintain since the information where the input was not accepted would be lost to the caller.
So what I can do in that case? Is it a good idea to throw unchecked exception here?
That depends on whether that exception should be handled at runtime or be fixed.
Suppose the caller needs to know that the sequence was invalid and should handle that information appropriately, e.g. display some information to the enduser. In that case it would be better to throw a checked exception that describes that case.
On the other hand, if the input violates the contract of the method, i.e. the input sequence should never be invalid (or otherwise it's a programming error) then an IllegalArgumentException would be ok - situations like passing null to a method that doesn't expect null parameters.
And is a good idea to throw exception inside inspectSequence method or I should return null when supplied String isn't valid and then check returned result in add method and depending on it throw or not throw exception?
I'd say no. Returning null and then handling that in the calling method might be a reasonable way in some cases (e.g. if you have different callers that handle null differently) but your case is none of those. It would make code more complex and thus harder to read and maintain, especially since null might have multiple meanings which you'd have to define in that case.
You can catch IllegalArgumentException and throw your own.
public void add(String sequence) throws MyCustomException {
try {
inspectSequence(sequence);
} catch (IllegalArgumentException e) {
throw new MyCustomException("more readable cause that hides internals");
}
}
Do you know some nice alternative to Apache Commons Validate or Guava Preconditions that would throw IllegalArgumentException instead of NullPointerException when checking if object is not null (except Spring Assert)?
I'm aware that Javadocs say:
Applications should throw instances of this class [NullPointerException] to indicate other
illegal uses of the null object.
Nevertheless, I just don't like it. For me NPE was always meaning I just forgot to secure null reference somewhere. My eyes are so trained, I could spot it browsing logs with a speed of few pages per second and if I do there is always bug alert in my head enabled. Therefore, it would be quite confusing for me to have it thrown where I expect an IllegalArgumentException.
Say I have a bean:
public class Person {
private String name;
private String phone;
//....
}
and a service method:
public void call(Person person) {
//assert person.getPhone() != null
//....
}
In some context it may be ok, that a person has no phone (my grandma doesn't own any). But if you'd like to call such person, for me it's calling the call method with an IllegalArgument passed. Look at the hierarchy - NullPointerException is not even a subclass of IllegalArgumentException. It basically tells you - Again you tried to call a getter on null reference.
Besides, there were discussions already and there is this nice answer I fully support. So my question is just - do I need to do ugly things like this:
Validate.isTrue(person.getPhone() != null, "Can't call a person that hasn't got a phone");
to have it my way, or is there a library that would just throw IllegalArgumentException for a notNull check?
Since the topic of this question evolved into "Correct usage of IllegalArgumentException and NullpointerException", I would like to point out the strait forward answer in Effective Java Item 60 (second edition):
Arguably, all erroneous method invocations boil down to an illegal argument
or illegal state, but other exceptions are standardly used for certain kinds of illegal
arguments and states. If a caller passes null in some parameter for which null values
are prohibited, convention dictates that NullPointerException be thrown
rather than IllegalArgumentException. Similarly, if a caller passes an out-ofrange
value in a parameter representing an index into a sequence, IndexOutOfBoundsException
should be thrown rather than IllegalArgumentException.
What about Preconditions's checkArgument?
public void call(Person person) {
Preconditions.checkArgument(person.getPhone() != null);
// cally things...
}
checkArgument throws IllegalArgumentException instead of NullPointerException.
You can use valid4j with hamcrest-matchers (found on Maven Central as org.valid4j:valid4j). The 'Validation' class has support for regular input validation (i.e. throwing recoverable exceptions):
import static org.valid4j.Validation.*;
validate(argument, isValid(), otherwiseThrowing(InvalidException.class));
Links:
http://www.valid4j.org/
https://github.com/valid4j/valid4j
On a side-note: This library also has support for pre- and post-conditions (like assertions really), and it's possible to register your own customized global policy, if needed:
import static org.valid4j.Assertive.*;
require(x, greaterThan(0)); // throws RequireViolation extends AssertionError
...
ensure(r, notNullValue()); // throws EnsureViolation extends AssertionError
Take a look at https://github.com/cowwoc/requirements.java/ (I'm the author). You can override the default exception type using withException() as follows:
new Verifiers().withException(IllegalArgumentException.class).requireThat(name, value).isNotNull();
Not that I'm aware of. I'd just roll your own to get the behavior you want with a concise invocation, mimicking Guava's implementation but tweaking the exception type.
class Preconditionz {
public static <T> T checkNotNull(T reference, Object errorMessage) {
if (reference == null) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
}
return reference;
}
}
I like to go ahead and import static these really frequently used methods, too, so you can call them super concisely.
import static com.whatever.util.Preconditionz.checkNotNull;
// ...
public void call(Person person) {
checkNotNull(person, "person");
checkNotNull(person.getPhone(), "person.phone");
// ...
}
Depending on your environment, you might want to name it checkNotNull2 so it's easier to add the import via autocompletion in your IDE, or let you use it alongside the standard checkNotNull.
I guess I learned something again here on SO thanks to great comments by Olivier Grégoire, Louis Wasserman, CollinD and Captain Man.
The standards are ussually a strong and sufficient reason as they make the common language programmers will always understand correctly, but in this particular case I had this little doubt, that maybe this rule set around NPE isn't too ok. Java is an old language and some of its features came up to be a bit unlucky (I don't want to say wrong, that's maybe too strong judgment) - like checked exceptions, although you may also disagree. Now I think that this doubt is resolved and I should:
Throw an IllegalArgumentException when in the particular context I can tell why the null value is wrong rather from the business perspective. For instance in the service method public void call(Person person) I know what does it mean to the system that the phone number is null.
Throw a NullPointerException when I just know that the null value here is wrong and will sooner or later cause a NullPointerException, but in the particular context I'm unaware what does it mean from the business perspective. The example would be Guavas immutable collections. When you build such and try to add an element of a null value it throws you a NPE. It doesn't understand what this value mean for you, it's too generic, but it just knows it's wrong here, so it decides too tell you this immediately, with some more appropriate message, so that you can recognize the problem more effectively.
Having above in mind I would say the best option to make the assertion in the public void call(Person person) example is like Captain Man suggests:
Preconditions.checkArgument(person.getPhone() != null, "msg");
Check argument is a good name for this method - it's clear that I'm checking the business contract compliance against the person argument and it's clear that I'm expecting IllegalArgumentException if it fails. It's a better name than the Validate.isTrue of Apache Commons. Saying Validate.notNull or Preconditions.checkNotNull on the other hand suggest that I'm checking for a null reference and I'm actually expecting the NPE.
So the final answer would be - there is no such nice library and shouldn't be as this would be confusing. (And Spring Assert should be corrected).
You can easily do this:
if (person.getPhone() == null) {
throw new IllegalArgumentException("Can't call a person that hasn't got a phone");
}
It is clear to other programmers what you mean, and does exactly what you want.
I'm working on making a codebase complaint with a list of PMD rules. These include that you're not allowed to throw or catch NullPointerExceptions. I found this method which requires 2 instance variables to be non-null in order to run. It throws a NullPointerException otherwise:
public String build() {
if (apiKey == null || url == null) {
throw new NullPointerException(
"Cannot build: API key and URL must be set");
}
What should it be throwing instead? it seems to me that NullPointerException would be the bast call. The only other thing that comes to mind is IllegalArgumentException, but these aren't really arguments, so I don't think it really fits.
IllegalStateException seems entirely appropriate here:
Signals that a method has been invoked at an illegal or inappropriate time.
That describes the situation reasonably clearly, doesn't it?
IllegalStateException springs to mind.
One thing to consider here is whether this should be a checked or an unchecked exception. You could also consider making your own explicit Exception for this case if it can usefully be handled differently from the generic IllegalStateException.
I have a question about best practices in Java. I'm writing a class, which relies on an object at construction pretty heavily. In fact, if the object passed in at construction is null, most of the functionality wouldn't make sense. I thought it best to throw an exception in the case where null is passed as an argument at object construction, but I don't know what the most appropriate exception would be in this case. Should I throw a NullPointer, IllegalArgument, Instatiation, or even an Initialization exception.
I've seen these all used throughout the Java source codebase, and I don't seem to be able to distinguish why a NullPointer was used in some cases and IllegalArgument used in others. I personally would have thought that if a bad argument is passed in at construction, some initialization error should occur.
Firstly, you should absolutely throw an exception. It's simply the Right Thing To Do.
As for whether you should throw IllegalArgumentException or NullPointerException - Josh Bloch talks about this in Effective Java, and generally concludes that NullPointerException is a reasonable choice. I'm not entirely sure I agree (I would probably have picked IllegalArgumentException), but ultimately it's unlikely to matter: you shouldn't be catching either of these exceptions directly, and the stack trace will show you where there's a problem anyway.
(It's a shame Java doesn't have the equivalent to .NET's ArgumentNullException, which means exactly what it sounds like.)
Personally I'm a big fan of Guava's Preconditions class:
public class Foo {
private final Bar bar;
public Foo(Bar bar) {
this.bar = Preconditions.checkNotNull(bar);
}
}
(Sometimes used with a static import of checkNotNull.)
IllegalArgument makes it clear, to the developer who's used the code, what the problem is and how to fix it I would say. It also makes it clear that the method CANNOT work without that object.
NullPointer means they have to think a little bit about what the problem is (not much) and may mean the code is cleaner, but like I said above. It's not immediately clear, from a documentation point-of-view whether your code can work with a null value or not.
If you think the platform exceptions do not give the client the right amount of information to understand and fix the issue, you can create your own exception that's more appropriate in that regard, say like .NET's ArgumentNullException; which will tell the client both what the problem is and how to fix it.
NullPointerException is used when you are expecting a valid object but get null instead. This is especially pertinent when trying to call methods on a null object. This is the most common use for it. However, your case may also warrant it.
IllegalArgumentException is used when you received an argument into a method that is not what you expect or of the wrong type/style/etc. This, in my view, would be more appropriate in your case. You expect a valid object, but you received null as an argument. This argument value is invalid - so I would throw IllegalArgumentException and in the message of the exception specify what's wrong, e.g.:
public MyClass(InputObject obj) {
if(obj == null) {
throw new IllegalArgumentException("null passed to MyClass constructor");
}
...
}