Mike gave an excellent answer that, unfortunately, is seldom defended in the Java literature. Some extra support to Mike's views:
The vast majority of the Java literature propagates the dogma that you should not use assert
to check public method arguments. In other words, they are saying that assert
should not be used to check
preconditions on public methods, and that you should instead use explicit if (!precond) throw SomeException();
instructions.
The standard Java library is full of examples of this policy.
The arguments to support this seem to be:
- Responsibility for satisfying the preconditions is with the function caller (the client's code) and so not "your" code (the supplier's code).
- Assertion checking is optional, so you'd better force the checking.
Well, this seems a very patronizing attitude to me. The clients of your code are programmers, just like you. Satisfying the preconditions is the clients' responsibility, of course, and if the clients don't do it, it's a bug; the clients' bug, not yours. Certainly, you expect your clients to check their programs with enabled assertions, don't you?
But once they are convinced of their program's correctness, why should you still force your useless exceptions on them?
Now, look at it from the client's perspective. You're using String.charAt
. The documentation for this method tells you that
public char charAt(int index)
Returns the char value at the specified index. An index ranges from 0 to
length() - 1. [...]
The precondition is clearly stated.
But later it adds
Throws:
IndexOutOfBoundsException - if the index argument is negative or not less than the length of this string.
So, if you know for sure that your index is within bounds, will you still put your call inside a try ... catch
? Notice that the documentation does not really tell you that the exception won't be thrown if you respect the precondition, but of course that's what you expect, isn't it?
So, you're sure that the index is within bounds, you may have even asserted that previously, and you won't waste time and space with a useless try
that will never catch anything, but the String
will still be wasting time checking that you were behaving well.
The way I see it,
- Assertions should be used to check conditions that are entirely under the control of a programmer, be it the client or the supplier.
- Explicit conditional instructions with exceptions (or another error signalling device like an error return code) should be used to check conditions that depend on uncontrollable external factors, like user input, unpredictable operating system restrictions, etc.
This is what I teach my students. I don't tell them. It's not a dogma. I let them know this is opposite to what they'll read in most books, but I urge them to decide for themselves.
This question is not specific to Java; it is a question on programming methodology.
The approach I follow is akin to design by contract. Some languages have special syntax for supporting this style, such as the possibility of explicitly declaring preconditions, postconditions and object invariants, and these are clearly included as part of the public specification (and documentation) of the code.
public
keyword in Java. It has to do with "public interfaces" or APIs that will be made available for use for others outside of your programming team. – Enchorial