Checked or Unchecked Exception [duplicate] - java

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
When to choose checked and unchecked exceptions
Hello!
So, I'm still getting comfortable regarding when to throw a checked or unchecked exception. I would like to know what others think is the most appropriate in this case:
class Correlation<T>
{
private final T object1, object2;
private final double correlationCoefficient;
public Correlation(T object1, T object2, double correlationCoefficient)
{
if(Math.abs(correlationCoefficient) > 1.0 || (object1.equals(object2) && correlationCoefficient != 1.0))
throw new IllegalArgumentException();
this.object1 = object1;
this.object2 = object2;
this.correlationCoefficient = correlationCoefficient;
}
}
So, in this case, I would like to throw a runtime exception because I cannot easily recover from a situation where the user passes in bad data. I would like to point out beforehand that I have no control over the data being passed in. If I could, I would create an interface which guarantees that the conditional in the constructor is true. However, this is a convenience class for correlations that have already been computed, so I have to trust that the user is providing accurate information.
Okay, let me know what you all think!

I think this is the correct response. You are effectively doing barrier asserts, i.e. barrier checks, and if they are wrong you are refusing to create the entity. I would document with a java doc that you can throw an IllegalArgumentException, however outside of that, it looks correct.
Joshua Block has some great information regarding checked and unchecked exceptions. The basic premise is that, unless you absolutely want someone checking for the exception, you should throw an unchecked exception. Thinking this way can complicate some coding and return values, but in general it makes for cleaner, more efficient code. Use exceptions for exceptional cases, and things will work better for you.
Just my 2 cents.
Edit
Just to be clear, here is something like the java doc you should have:
/**
* <Something describing constructor, and what it does, ending with a period.>
*
* #param parameter <Describe the parameter - do one for each parameter of the constructor,
* and note which values may be illegal for that particular parameter.>
* #throws IllegalArgumentException <the case for the illegal argument exception.>

In my opinion, the answer hinges on:
Do you expect the caller to be able to recover gracefully?
Is this API intended for public or internal consumption?
Someone people will tell you that you should never use checked exceptions. That's purely subjective.

You should ALWAYS include an explanatory text in your exception. In this particular case you might even consider have TWO checks:
if(Math.abs(correlationCoefficient) > 1.0)
throw new IllegalArgumentException("abs(correlationCoefficient) > 1.0 - " + correlationCoefficient);
if((object1.equals(object2) && correlationCoefficient != 1.0))
throw new IllegalArgumentException("object1==object2, but correlationCoefficient != 1.0, " + correlationCoefficient);
This allows those who actually get to see the stacktrace to be able to identify the exact cause without having to look intimately at the code. A given exception should only be triggered by ONE condition, not several, since you will not be certain what happended. Also include all necessary information as this may be crucial if the error situation cannot be reproduced in a test scenario.

Related

Why not have Jave methods return a tuple instead of an object reference (or null)?

Typically Java methods look like:
public <U,V> U doSomething(V aReference) {
// Do something
}
This typically means that the method doSomething() returns a null if it
fails (for whatever reason) or a valid object reference. In some cases the
"valid object reference" may itself be null. For example, the method
aMap.get(k) may return null if there is no key k or if there is a key
k but its corresponding value is null. Confusion!
Not to mention NullPointerExceptions if 50% of your LOC isn't just
null-checking.
What's wrong with methods looking like this:
public <T> ReturnTuple<T> doSomething(V aReference) {
T anotherObjRef = getValidObjT();
if (successful) {
return ReturnTuple.getSuccessTuple(anotherObjRef);
} else {
return ReturnTuple.getFailureTuple("aReference can't be null");
}
}
where the class ReturnTuple<T> is defined something like:
class ReturnTuple<T> {
private boolean success;
// Read only if success == true
private T returnValue;
// Read only if success == false
private String failureReason;
// Private constructors, getters, setters & other convenience methods
public static <T> ReturnTuple<T> getSuccessTuple(T retVal) {
// This code is trivial
}
public static <T> ReturnTuple<T> getFailureTuple(String failureReason) {
// This code is trivial
}
}
Then the calling code will look like:
ReturnTuple<T> rt = doSomething(v);
if (rt.isSuccess()) {
// yay!
} else {
// boo hoo!
}
So, my question is: why isn't this pattern more common? What is wrong with it?
Keep in mind I am not asking for a critique of this exact code, but for a
critique of this general idea.
Please note: the point here is not to get the code above to compile, just to
discuss an idea. So please don't be too pedantic about code correctness :-).
Edit 1: Motivation
I guess I should have added this section from the beginning, but better late
than never...
Ever wished a method could return two values at once? Or that the returning
of a value could be de-linked from the ability to indicate success or
failure?
This could also promote the idea of a method being a neat-and-clean
self-contained unit (low coupling and high cohesion): handle all (or most)
exceptions generated during it's execution (not talking about exceptions
like IllegalArgumentException), discreetly log failure reasons (rather
than the ugly stack trace of an uncaught exception) and only bother the
caller with exactly the information required. IMHO this also promotes
information-hiding and encapsulation.
Done your best with testing, but when the code is deployed to the customer,
an uncaught exception's ugly stack trace makes it all look so
unprofessional.
Similar to the point above: you may have code that could possibly generate
20 different exceptions but you're catching only 5-7 of those. As we all
know, customers do the damndest things: rely on them to cause all the other
uncaught 13-15 exceptions :-). You end up looking bad when they see a big
stack trace (instead of a discrete failure reason added to the logs).
This is the difference (for example) between showing a stack trace to a
user in a web app vs. showing them a nicely formatted 5xx error page saying
something like: "There was an error and your request couldn't be completed.
Admins have been notified and will fix as soon as possible." etc.
This idea isn't entirely without merit as Java 8 provides the
Optional
class (as pointed out by #JBNizet) and Google's
Guava library also has an
Optional
class. This just takes that a little further.
This typically means that the method doSomething() returns a null if it fails
No, it does not mean that. It means that the method doSomething() may sometimes legally return null, without a failure. Java provides a powerful system for handling failures - namely, exception handling. This is how the API should indicate failures.
why isn't this [return a tuple] pattern more common? What is wrong with it?
The primary thing that is wrong with this pattern is that it is using a mechanism of reporting failures in a way that is foreign to Java. If your API runs into a failure, throw an exception. This saves you from creating twice as many objects as needed in "mainstream" cases, and keeps your APIs intuitively understandable to people who learned the Java class library well.
There are situations when returning a null can be interpreted both ways - as a failure, and as a legitimate return value. Looking up objects in associative containers provide a good example: when you supply a key that is not in the map, one could claim that that is a programming error and throw an exception (.NET class library does that) or claim that when the key is missing, the corresponding spot in the map contains the default value, i.e. a null - the way this is done in Java. In situations like that it is entirely acceptable to return a tuple. Java's Map decided against this, most likely to save on creating additional objects every time an object is requested from a Map.

When should an IllegalArgumentException be thrown?

I'm worried that this is a runtime exception so it should probably be used sparingly.
Standard use case:
void setPercentage(int pct) {
if( pct < 0 || pct > 100) {
throw new IllegalArgumentException("bad percent");
}
}
But that seems like it would force the following design:
public void computeScore() throws MyPackageException {
try {
setPercentage(userInputPercent);
}
catch(IllegalArgumentException exc){
throw new MyPackageException(exc);
}
}
To get it back to being a checked exception.
Okay, but let's go with that. If you give bad input, you get a runtime error. So firstly that's actually a fairly difficult policy to implement uniformly, because you could have to do the very opposite conversion:
public void scanEmail(String emailStr, InputStream mime) {
try {
EmailAddress parsedAddress = EmailUtil.parse(emailStr);
}
catch(ParseException exc){
throw new IllegalArgumentException("bad email", exc);
}
}
And worse - while checking 0 <= pct && pct <= 100 the client code could be expected to do statically, this is not so for more advanced data such as an email address, or worse, something that has to be checked against a database, therefore in general client code cannot pre-validate.
So basically what I'm saying is I don't see a meaningful consistent policy for the use of IllegalArgumentException. It seems it should not be used and we should stick to our own checked exceptions. What is a good use case to throw this?
The API doc for IllegalArgumentException:
Thrown to indicate that a method has been passed an illegal or inappropriate argument.
From looking at how it is used in the JDK libraries, I would say:
It seems like a defensive measure to complain about obviously bad input before the input can get into the works and cause something to fail halfway through with a nonsensical error message.
It's used for cases where it would be too annoying to throw a checked exception (although it makes an appearance in the java.lang.reflect code, where concern about ridiculous levels of checked-exception-throwing is not otherwise apparent).
I would use IllegalArgumentException to do last ditch defensive argument checking for common utilities (trying to stay consistent with the JDK usage). Or where the expectation is that a bad argument is a programmer error, similar to an NullPointerException. I wouldn't use it to implement validation in business code. I certainly wouldn't use it for the email example.
When talking about "bad input", you should consider where the input is coming from.
Is the input entered by a user or another external system you don't control, you should expect the input to be invalid, and always validate it. It's perfectly ok to throw a checked exception in this case. Your application should 'recover' from this exception by providing an error message to the user.
If the input originates from your own system, e.g. your database, or some other parts of your application, you should be able to rely on it to be valid (it should have been validated before it got there). In this case it's perfectly ok to throw an unchecked exception like an IllegalArgumentException, which should not be caught (in general you should never catch unchecked exceptions). It is a programmer's error that the invalid value got there in the first place ;) You need to fix it.
Throwing runtime exceptions "sparingly" isn't really a good policy -- Effective Java recommends that you use checked exceptions when the caller can reasonably be expected to recover. (Programmer error is a specific example: if a particular case indicates programmer error, then you should throw an unchecked exception; you want the programmer to have a stack trace of where the logic problem occurred, not to try to handle it yourself.)
If there's no hope of recovery, then feel free to use unchecked exceptions; there's no point in catching them, so that's perfectly fine.
It's not 100% clear from your example which case this example is in your code, though.
Treat IllegalArgumentException as a preconditions check, and consider the design principle: A public method should both know and publicly document its own preconditions.
I would agree this example is correct:
void setPercentage(int pct) {
if( pct < 0 || pct > 100) {
throw new IllegalArgumentException("bad percent");
}
}
If EmailUtil is opaque, meaning there's some reason the preconditions cannot be described to the end-user, then a checked exception is correct. The second version, corrected for this design:
import com.someoneelse.EmailUtil;
public void scanEmail(String emailStr, InputStream mime) throws ParseException {
EmailAddress parsedAddress = EmailUtil.parseAddress(emailStr);
}
If EmailUtil is transparent, for instance maybe it's a private method owned by the class under question, IllegalArgumentException is correct if and only if its preconditions can be described in the function documentation. This is a correct version as well:
/** #param String email An email with an address in the form abc#xyz.com
* with no nested comments, periods or other nonsense.
*/
public String scanEmail(String email)
if (!addressIsProperlyFormatted(email)) {
throw new IllegalArgumentException("invalid address");
}
return parseEmail(emailAddr);
}
private String parseEmail(String emailS) {
// Assumes email is valid
boolean parsesJustFine = true;
// Parse logic
if (!parsesJustFine) {
// As a private method it is an internal error if address is improperly
// formatted. This is an internal error to the class implementation.
throw new AssertError("Internal error");
}
}
This design could go either way.
If preconditions are expensive to describe, or if the class is intended to be used by clients who don't know whether their emails are valid, then use ParseException. The top level method here is named scanEmail which hints the end user intends to send unstudied email through so this is likely correct.
If preconditions can be described in function documentation, and the class does not intent for invalid input and therefore programmer error is indicated, use IllegalArgumentException. Although not "checked" the "check" moves to the Javadoc documenting the function, which the client is expected to adhere to. IllegalArgumentException where the client can't tell their argument is illegal beforehand is wrong.
A note on IllegalStateException: This means "this object's internal state (private instance variables) is not able to perform this action." The end user cannot see private state so loosely speaking it takes precedence over IllegalArgumentException in the case where the client call has no way to know the object's state is inconsistent. I don't have a good explanation when it's preferred over checked exceptions, although things like initializing twice, or losing a database connection that isn't recovered, are examples.
As specified in oracle official tutorial , it states that:
If a client can reasonably be expected to recover from an exception,
make it a checked exception. If a client cannot do anything to recover
from the exception, make it an unchecked exception.
If I have an Application interacting with database using JDBC , And I have a method that takes the argument as the int item and double price. The price for corresponding item is read from database table. I simply multiply the total number of item purchased with the price value and return the result. Although I am always sure at my end(Application end) that price field value in the table could never be negative .But what if the price value comes out negative? It shows that there is a serious issue with the database side. Perhaps wrong price entry by the operator. This is the kind of issue that the other part of application calling that method can't anticipate and can't recover from it. It is a BUG in your database. So , and IllegalArguementException() should be thrown in this case which would state that the price can't be negative.
I hope that I have expressed my point clearly..
Any API should check the validity of the every parameter of any public method before executing it:
void setPercentage(int pct, AnObject object) {
if( pct < 0 || pct > 100) {
throw new IllegalArgumentException("pct has an invalid value");
}
if (object == null) {
throw new IllegalArgumentException("object is null");
}
}
They represent 99.9% of the times errors in the application because it is asking for impossible operations so in the end they are bugs that should crash the application (so it is a non recoverable error).
In this case and following the approach of fail fast you should let the application finish to avoid corrupting the application state.

How do you document unchecked exceptions? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Joshua Bloch in his Effective Java writes :
"Use the Javadoc #throws tag to document each unchecked exception that
a method can throw, but do not use the throws keyword to include unchecked
exceptions in the method declaration. "
Well that sounds reasonable indeed, but how to find out, what unchecked exception can my method throw?
Let's think of a following class :
public class FooClass {
private MyClass[] myClass;
/**
* Creates new FooClass
*/
public FooClass() {
// code omitted
// do something with myClass
}
/**
* Performs foo operation.<br />
* Whatever is calculated.
* #param index Index of a desired element
* #throws HorribleException When something horrible happens during computation
*/
public void foo(int index) {
try {
myClass[index].doComputation();
} catch (MyComputationException e) {
System.out.println("Something horrible happened during computation");
throw new HorribleException(e);
}
}
}
Now, I documented HorribleException, but it is quite obvious, that foo method can also throw unchecked java.lang.ArrayIndexOutOfBoundsException. The more complex the code gets, it's harder to think of all unchecked exceptions that method can throw. My IDE doesn't help me much there and nor does any tool. Since I don't know any tool for this ...
How do you deal with this kind of situation?
Only document those which you're explicitly throwing yourself or are passing through from another method. The remnant is to be accounted as bugs which are to be fixed by good unit testing and writing solid code.
In this particular case, I'd account ArrayIndexOutOfBoundsException as a bug in your code and I'd fix the code accordingly that it never throws it. I.e. add a check if the array index is in range and handle accordingly by either throwing an exception -which you document- or taking an alternative path.
The more complex the code gets, it's harder to think of all unchecked exceptions that method can throw.
Where you see a problem, I see a very good reason to keep your code simple ;-)
In your exemple, I'd suggest to document the ArrayIndexOutOfBoundsException. Just because that's something someone can have when giving a bad parameter to you method, and it should be written somewhere : "If you given an invalid array index, you'll get an ArrayIndexOutOfBoundsException. For example, the String#charAt() method documents it can throw an IndexOutOfBoundException if the index isn't valid.
In general, you shouldn't document al the exceptions that can arise. You can't predict them all, and you're very likely to forget one. So, document the obvious ones, the one you though of. Try to list the most exceptions as possible, but don't spend to much time on it. After all, if you forget one that should be documented, you can improve your documentation later.
Document only what you're throwing yourself.
In this case, I'd go for a index bounds check and throw my own exception:
throw IllegalArgumentException("Index must be smaller than " +myClass.length + ", but is: " + index)
and then document the IllegalArgumentException in the JavaDoc.
The quote you posted, is just something you have to keep in mind if you want to be the ideal programmer. Programming is not thinking "what can go wrong", but is think how to do something the best way and program it. If it is a personal project, just write what the method does.
However, there are three possible solutions:
Do not document the method.
Think a minute of what your code does and find out what the most common possible unchecked exceptions could be. Add them to the Java-doc. And if you encounters a new one, find out what the problem is and add it as possible exception.
Do not care about the possible exceptions and document only the exceptions you throw in the method body (like: if (obj == null) { throw new NullPointerException(); }).
We have a written checkstyle extension that run on our test server. In your sample it would test if HorribleException was documented.
The ArrayIndexOutOfBoundsException will detect with a code review. In your sample code our goals required to throw a InvalidArgumentException instead a ArrayIndexOutOfBoundsException. The documentation of it will be find from test server.
The ArrayIndexOutOfBoundsException can be a warning in FindBugs. But I am not sure.

Is returning null after exception is caught bad design [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return. The following code snippet illustrates my problem.
public Object getObject(){
try{
...
return object;
}
catch(Exception e){
//I have to return something here but what??
return null; // is this a bad design??
}
}
So my questions are:
Is return null bad design?
If so what is seen as a cleaner solution??
thanks.
I would say don't catch the exception if you really can't handle it. And logging isn't considered handling an error. Better to bubble it up to someone who can by throwing the exception.
If you must return a value, and null is the only sensible thing, there's nothing wrong with that. Just document it and make it clear to users what ought to be done. Have a unit test that shows the exception being thrown so developers coming after you can see what the accepted idiom needs to be. It'll also test to make sure that your code throws the exception when it should.
I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return.
If you don't know what to return, then it means that you don't know how to handle the exception. In that case, re-throw it. Please, don't swallow it silently. And please, don't return null, you don't want to force the caller of the code to write:
Foo foo = bar.getFoo();
if (foo != null) {
// do something with foo
}
This is IMHO a bad design, I personally hate having to write null-checks (many times, null is used where an exception should be thrown instead).
So, as I said, add a throws clause to the method and either totally remote the try/catch block or keep the try/catch if it makes sense (for example if you need to deal with several exceptions) and rethrow the exception as is or wrap it in a custom exception.
Related questions
How to avoid “!= null” statements in Java?
Above all I prefer not to return null. That's something that the user has to explicitly remember to handle as a special case (unless they're expecting a null - is this documented). If they're lucky they'll deference it immediately and suffer an error. If they're unlucky they'll stick it in a collection and suffer the same problem later on.
I think you have two options:
throw an exception. This way the client has to handle it in some fashion (and for this reason I either document it and/or make it checked). Downsides are that exceptions are slow and shouldn't be used for control flow, so I use this for exceptional circumstances (pun intended)
You could make use of the NullObject pattern.
I follow a coding style in which I rarely return a null. If/when I do, that's explicitly documented so clients can cater for it.
Exceptions denote exceptional cases. Assuming your code was supposed to return an object, something must have gone wrong on the way (network error, out of memory, who knows?) and therefore you should not just hush it by returning null.
However, in many cases, you can see in documentation that a method returns a null when such and such condition occurs. The client of that class can then count on this behaviour and handle a null returned, nothing bad about that. See, in this second usage example, it is not an exceptional case - the class is designed to return null under certain conditions - and therefore it's perfectly fine to do so (but do document this intended behaviour).
Thus, at the end of the day, it really depends on whether you can't return the object because of something exceptional in your way, or you simply have no object to return, and it's absolutely fine.
I like the responses that suggest to throw an exception, but that implies that you have designed exception handling into the architecture of your software.
Error handling typically has 3 parts: detection, reporting, and recovery. In my experience, errors fall into classes of severity (the following is an abbreviated list):
Log for debug only
Pause whatever is going on and report to user, waiting for response to continue.
Give up and terminate the program with an apologetic dialogue box.
Your errors should be classified and handling should be as generically and consistently as possible. If you have to consider how to handle each error each time you write some new code, you do not have an effective error handling strategy for your software. I like to have a reporting function which initiates user interaction should continuation be dependent on a user's choice.
The answer as to whether to return a null (a well-worn pattern if I ever saw one) then is dependent on what function logs the error, what can/must the caller do if the function fails and returns the null, and whether or not the severity of the error dictates additional handling.
Exceptions should always be caught by the controller in the end.
Passing a <null> up to the controller makes no sense.
Better to throw/return the original exception up the stack.
It's your code and it's not bad solution. But if you share your code you Shoudn't use it because it can throw unexpected exception (as nullpointer one).
You can of course use
public Object getObject() throws Exception {}
which can give to parent function usable information and will warn that something bad can happen.
Basically I would ditto on Duffymo, with a slight addition:
As he says, if your caller can't handle the exception and recover, then don't catch the exception. Let a higher level function catch it.
If the caller needs to do something but should then appropriately die itself, just rethrow the exception. Like:
SomeObject doStuff()
throws PanicAbortException
{
try
{
int x=functionThatMightThrowException();
... whatever ...
return y;
}
catch (PanicAbortException panic)
{
cleanUpMess();
throw panic; // <-- rethrow the exception
}
}
You might also repackage the exception, like ...
catch (PanicAbortException panic)
{
throw new MoreGenericException("In function xyz: "+panic.getMessage());
}
This is why so much java code is bloated with if (x!=null) {...} clauses. Don't create your own Null Pointer Exceptions.
I would say it is a bad practice. If null is received how do I know if the object is not there or some error happened?
My suggestion is
never ever return NULL if the written type is an array or
Collection. Instead, return an empty Collection or an empty array.
When the return type is an object, it is up to you to return null depending on the scenario. But never ever swallow an exception and return NULL.
Also if you are returning NULL in any scenario, ensure that this is documented in the method.
As Josha Blooch says in the book "Effective Java", the null is a keyword of Java.
This word identifies a memory location without pointer to any other memory location: In my opinion it's better to coding with the separation of behavior about the functional domain (example: you wait for an object of kind A but you receive an object of kind B) and behavior of low-level domain (example: the unavailability of memory).
In your example, I would modify code as :
public Object getObject(){
Object objectReturned=new Object();
try{
/**business logic*/
}
catch(Exception e){
//logging and eventual logic leaving the current ojbect (this) in a consistent state
}
return objectReturned;
}
The disadvantage is to create a complete Object in every call of getObject() (then in situation where the object returned is not read or write).
But I prefer to have same object useless than a NullPointerException because sometimes this exception is very hard to fix.
Some thoughts on how to handle Exceptions
Whether returning null would be good or bad design depends on the Exception and where this snippet is placed in your system.
If the Exception is a NullPointerException you probably apply the catch block somewhat obtrusive (as flow control).
If it is something like IOException and you can't do anything against the reason, you should throw the Exception to the controller.
If the controller is a facade of a component he, translate the Exception to well documented component-specific set of possible Exceptions, that may occur at the interface. And for detailed information you should include the original Exception as nested Exception.

Passing null to a method [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I am in the middle of reading the excellent Clean Code
One discussion is regarding passing nulls into a method.
public class MetricsCalculator {
public double xProjection(Point p1, Point p2) {
return (p2.x - p1.x) * 1.5;
}
}
...
calculator.xProjection(null, new Point(12,13));
It represents different ways of handling this:
public double xProjection(Point p1, Point p2) {
if (p1 == null || p2 == null) {
throw new IllegalArgumentException("Invalid argument for xProjection");
}
return (p2.x - p1.x) * 1.5;
}
public double xProjection(Point p1, Point p2) {
assert p1 != null : "p1 should not be null";
assert p2 != null : "p2 should not be null";
return (p2.x - p1.x) * 1.5;
}
I prefer the assertions approach, but I don't like the fact that assertions are turned off by default.
The book finally states:
In most programming languages there is no good way to deal with a null that is passed by a caller accidentally. Because this is the case, the rational approach is to forbid passing null by default.
It doesn't really go into how you would enforce this restriction?
Do any of you have strong opinions either way.
General rule is if your method doesn't expect null arguments then you should throw System.ArgumentNullException. Throwing proper Exception not only protects you from resource corruption and other bad things but serves as a guide for users of your code saving time spent debugging your code.
Also read an article on Defensive programming
Both the use of assertions and the throwing of exceptions are valid approaches here. Either mechanism can be used to indicate a programming error, not a runtime error, as is the case here.
Assertions have the advantage of performance as they are typically disabled on production systems.
Exceptions have the advantage of safety, as the check is always performed.
The choice really depends on the development practices of the project. The project as a whole needs to decide on an assertion policy: if the choice is to enable assertions during all development, then I'd say to use assertions to check this kind of invalid parameter - in a production system, a NullPointerException thrown due to a programming error is unlikely to be able to be caught and handled in a meaningful way anyway and so will act just like an assertion.
Practically though, I know a lot of developers that don't trust that assertions will be enabled when appropriate and so opt for the safety of throwing a NullPointerException.
Of course if you can't enforce a policy for your code (if you're creating a library, for example, and so are dependent on how other developers run your code), you should opt for the safe approach of throwing NullPointerException for those methods that are part of the library's API.
Also not of immediate use, but related to the mention of Spec#... There's a proposal to add "null-safe types" to a future version of Java: "Enhanced null handling - Null-safe types".
Under the proposal, your method would become
public class MetricsCalculator {
public double xProjection(#Point p1, #Point p2) {
return (p2.x - p1.x) * 1.5;
}
}
where #Point is the type of non-null references to objects of type Point.
Spec# looks very interesting!
When something like that isn't available, I generally test non-private methods with a run-time null-check, and assertions for internal methods. Rather than code the null check explicitly in each method, I delegate that to a utilities class with a check null method:
/**
* Checks to see if an object is null, and if so
* generates an IllegalArgumentException with a fitting message.
*
* #param o The object to check against null.
* #param name The name of the object, used to format the exception message
*
* #throws IllegalArgumentException if o is null.
*/
public static void checkNull(Object o, String name)
throws IllegalArgumentException {
if (null == o)
throw new IllegalArgumentException(name + " must not be null");
}
public static void checkNull(Object o) throws IllegalArgumentException {
checkNull(o, "object");
}
// untested:
public static void checkNull(Object... os) throws IllegalArgumentException {
for(Object o in os) checkNull(o);
}
Then checking turns into:
public void someFun(String val1, String val2) throws IllegalArgumentException {
ExceptionUtilities.checkNull(val1, "val1");
ExceptionUtilities.checkNull(val2, "val2");
/** alternatively:
ExceptionUtilities.checkNull(val1, val2);
**/
/** ... **/
}
That can be added with editor macros, or a code-processing script.
Edit: The verbose check could be added this way as well, but I think it's significantly easier to automate the addition of a single line.
It doesn't really go into how you would enforce this restriction?
You enforce it by throwing an ArgumentExcexception if they pass in null.
if (p1 == null || p2 == null) {
throw new IllegalArgumentException("Invalid argument for xProjection");
}
In most programming languages there is no good way to deal with a null that is passed by a caller accidentally. Because this is the case, the rational approach is to forbid passing null by default.
I found JetBrains' #Nullable and #NotNull annotations approach for dealing with this the most ingenious, so far. It's IDE specific, unfortunately, but really clean and powerful, IMO.
http://www.jetbrains.com/idea/documentation/howto.html
Having this (or something similar) as a java standard would be really nice.
I prefer the use of assertions.
I have a rule that I only use assertions in public and protected methods. This is because I believe the calling method should ensure that it is passing valid arguments to private methods.
Although it is not strictly related you might want to take a look to Spec#.
I think it is still in development (by Microsoft) but some CTP are available and it looks promising. Basically it allows you to do this:
public static int Divide(int x, int y)
requires y != 0 otherwise ArgumentException;
{
}
or
public static int Subtract(int x, int y)
requires x > y;
ensures result > y;
{
return x - y;
}
It also provides another features like Notnull types. It's build on top of the .NET Framework 2.0 and it's fully compatible. The syntaxt, as you may see, is C#.
#Chris Karcher I would say absolutely correct. The only thing I would say is check the params separately and have the exeption report the param that was null also as it makes tracking where the null is coming from much easier.
#wvdschel wow! If writing the code is too much effort for you, you should look into something like PostSharp (or a Java equivalent if one is available) which can post-process your assemblies and insert param checks for you.
Since off-topic seems to have become the topic, Scala takes an interesting approach to this. All types are assumed to be not null, unless you explicity wrap it in an Option to indicate that it might be null. So:
// allocate null
var name : Option[String]
name = None
// allocate a value
name = Any["Hello"]
// print the value if we can
name match {
Any[x] => print x
_ => print "Nothing at all"
}
I generally prefer not doing either, since it's just slowing things down. NullPointerExceptions are thrown later on anyway, which will quickly lead the user to discovering they're passing null to the method. I used to check, but 40% of my code ended up being checking code, at which point I decided it was just not worth the nice assertion messages.
I agree or disagree with wvdschel's post, it depends on what he's specifically saying.
In this case, sure, this method will crash on null so the explicit check here is probably not needed.
However, if the method simply stores the passed data, and there is some other method that you call later that will deal with it, discovering bad input as early as possible is the key to fixing bugs faster. At that later point, there could be a myriad of ways that bad data happened to be given to your class. It's sort of trying to figure out how the rats came into your house after the fact, trying to find the hole somewhere.
Slightly off-topic, but one feature of findbugs that I think is very useful is to be able to annotate the parameters of methods to describe which parameters should not be passed a null value.
Using static analysis of your code, findbugs can then point out locations where the method is called with a potentially null value.
This has two advantages:
The annotation describes your intention for how the method should be called, aiding documentation
FindBugs can point to potential problem callers of the method, allowing you to track down potential bugs.
Only useful when you have access to the code that calls your methods, but that is usually the case.
Thwrowing C# ArgumentException, or Java IllegalArgumentException right at the beginning of the method looks to me as the clearest of solutions.
One should always be careful with Runtime Exceptions - exceptions that are not declared on the method signature. Since the compiler doesn't enforce you to catch these it's really easy to forget about them. Make sure you have some kind of a "catch all" exception handling to prevent the software to halt abruptly. That's the most important part of your user experience.
The best way to handle this really would be the use of exceptions. Ultimately, the asserts are going to end up giving a similar experience to the end user but provide no way for the developer calling your code to handle the situation before showing an exception to the end user. Ultimatley, you want to ensure that you test for invalid inputs as early as possible (especially in public facing code) and provide the appropriate exceptions that the calling code can catch.
In a Java way, assuming the null comes from a programming error (ie. should never go outside the testing phase), then leave the system throw it, or if there are side-effects reaching that point, check for null at the beginning and throw either IllegalArgumentException or NullPointerException.
If the null could come from an actual exceptional case but you don't want to use a checked exception for that, then you definitely want to go the IllegalArgumentException route at the beginning of the method.

Categories