Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should assertions not be used for argument checking in public methods?

Well, I have never really worked with assertions in my limited experience with Java and was wondering why I have read on a lot of sites and a lot of books that deal with assertions, the same warning that assert statements should not be used for argument checking in public methods?

I was wondering whether this had something to do with the order of execution of the assert statement relative to the other statements in Java.

like image 540
anonuser0428 Avatar asked Dec 12 '12 03:12

anonuser0428


People also ask

What is the advantage of assertion and where we should not use it?

According to Sun Specification, assertion should not be used to check arguments in the public methods because it should result in appropriate runtime exception e.g. IllegalArgumentException, NullPointerException etc. Do not use assertion, if you don't want any error in any situation.

What can cause an assertion statement to be ignored?

Assertions can be enabled or disabled when the program is started, and are disabled by default. Disabling assertions eliminates their performance penalty entirely. Once disabled, they are essentially equivalent to empty statements in semantics and performance.

Why are exceptions better than assertions?

Exceptions versus assertions Use assert statements to test for conditions during development that should never be true if all your code is correct. There's no point in handling such an error by using an exception, because the error indicates that something in the code has to be fixed.

Is it a good practice to use assert in Java?

Yes it is a very good practice to assert your assumptions. Read Design By Contract. assert can be used to verify pre conditions, invariants and post conditions during integration and testing phases. This helps to catch the errors while in development and testing phases.


1 Answers

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.

like image 165
João Manuel Rodrigues Avatar answered Nov 10 '22 13:11

João Manuel Rodrigues