This morning I had a discussion with one of my professors. He scolded me for having ugly code like if (x < 0) throw new IndexOutOfBoundsException("x should be non-negative");. He said a programmer should never have to throw NullPointerException, IndexOutOfBoundsException, IllegalArgumentException, etc. They are exceptions thrown by Java, and not for us mortals. Parameter checking is done purely with assert statements.
I argued that asserts are turned off in production, and that not having fail-fast behavior can be dangerous in some contexts.
Now, I told him I'd look for articles that supported my view, but after some digging around, most of what I can find are discussions on StackOverflow, and poorly written blogs. I don't think those, while numerous, will convince him. Is anyone aware of good articles on the matter, that either support or oppose my point of view? Thanks a lot.
Wow awesome, never actually thought of turning to Oracle.
By convention, preconditions on public methods are enforced by explicit checks that throw particular, specified exceptions. For example:
This convention is unaffected by the addition of the assert construct. Do not use assertions to check the parameters of a public method. An assert is inappropriate because the method guarantees that it will always enforce the argument checks. It must check its arguments whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type. It can throw only an AssertionError.
Look at, for example, the class java.util.Objects in the Java 8 API documentation. It contains a number of requireNonNull methods that you can use to check that arguments to a method are not null. It will throw a NullPointerException (with a customizable message) if you pass a null value into it.
Likewise, the popular Google Guava library has a class com.google.common.base.Preconditions with methods for checking arguments for a method. These methods throw IllegalArgumentException when the condition fails. So, it's certainly a common and well-accepted practice to throw IllegalArgumentException for invalid arguments.
In fact, the whole purpose of IllegalArgumentException is to be thrown when a method is passed an invalid argument. There's no reason why only the classes in the standard Java library should be allowed to throw this exception, you can use it yourself just as well. Especially when you're writing a library for other developers to use, I would consider it important to check method arguments in the public API of the library, and throw this exception if necessary.
I have since forever been confused on this. My current logic is this ( and it could be flawed ).
If a case should never happen and if it can happen only as a result of us programming incorrectly and the method in question is a private method, in some cases we could use assertions. But just because we used assertions in the called private method, it does not mean that we cannot have related Exception handlers in the calling method. For every other thing, I think we should use Exceptions.
For an IndexOutOfBoundException, it would also be important to see who is calling the method in question, i.e how is a value being assigned to x.
I think if a user is sending the value through a user interface, we should probably throw a RuntimeException. If it is a non private method, we should never use asserts.
If a non private method is calling a private method and sending x as an argument ( and x is supposed to be either the index of a String or an array ) to this private method, and the calling method should never have to send a value outside the range ( it's almost an impossible case - unless someone does so on purpose ), I think we could use assert statements in the private method cause probably if a method is private, it should never have to throw an uncaught Exception. But still I don't get this logic entirely cause the calling non private method can always have an Exception handler.
Personally I also don't understand why we should use asserts at all in production code but on the flip side I also believe that a private method should never have to throw an uncaught Exception. Also it feels like asserts are not for making sure that the method in which they appear ( the called method ) is correctly coded. They are for ensuring that the called method is correctly called by the calling method. But these are just observations.
So I'd also be looking forward to the articles/advice we get here.
Joined: Dec 25, 2013
Oh Ninja'd post.
Wow, there are many responses. I'm sure they will help me also. So thanks, everyone.
Heena Agarwal wrote:Personally I also don't understand why we should use asserts at all in production code but on the flip side I also believe that a private method should never have to throw an uncaught Exception. Also it feels like asserts are not for making sure that the method in which they appear ( the called method ) is correctly coded. They are for ensuring that the called method is correctly called by the calling method. But these are just observations.
Well, if you're going to use asserts, it doesn't matter if they end up in production, because they are disabled by default. So you might as well leave them in the code, because they also provide a clue to maintainers what the code is about.
Assertions are *exactly* for checking if code is correct. You put them in private methods to check if the calling code is correct, and you put them in any method to check whether the code within that method is itself correct.
Honestly, I never use them. I do parameter checking in all my methods, and it's usually more than enough to make debugging an easy task for me, i.e. when I get an exception, it's usually very close to where the bug is.
My professor's response amounted to that when you're not going to release code to programmers other than yourself, you can basically treat everything as private.
I'm not sure how I feel about this. I think I'll use asserts for his classes and then stubbornly use my own way the rest of the time.
Joined: Mar 22, 2005
Yeah, that seems an odd distinction. I shouldn't (and wouldn't want to) have to revisit and possibly change code just because someone else will now look at it (something that, in this day and age of team work and open source code, is common even if I didn't think of it to begin with).
I disagree about assert statements. Onc eyou release code on an unsuspecting world, it becomes impossible to check that correct parameters are being supplied. Since assertions are inactivated by default, you could not check for parameters. Therefore you need an IllegalArgumentException.
I'm still going through all your responses and the links posted in this thread. Hopefully this thread will have answered all my questions. If I'd still have questions, I will post them in a separate thread.
Joined: Oct 13, 2005
Pleased to have been able to help, but please post related questions here.