Why can't we use assertion for public methods?

The important distinction is whether you believe an incorrect value is the result of

a) A programming bug which should be fixed in code.

b) An input error which cannot be prevented in code and instead need to be handled at runtime.

For the first case, you should use an assert, as the program code will need to be fixed. If its the later case, you should use an appropriate Runtime or check exception.


IMHO assertions are for detecting programming errors and not user/external inputs. Perhaps the author is confusing public methods as an external input when you will have public method which are not called by an external input.

I would use assertions to check arguments to detect programming errors. IMHO this is often the best use for them. Private method by comparison should only be called by code in the same class and you should expect them to be well unit tests and have limited possible access/usages.

I find that you are far more likely to have programming error via public interfaces because different people make different assumptions (assertions are a good way to document and check assumptions) Internal checks are not as useful as you would expect the same programmer to have access to the internal code if not having written the whole internal code base.


Assertions should not be used for checking arguments in public methods for the following reasons:

  • assertions can be disabled and argument checks should never be disabled as they are part of the method's contract with its callers
  • assertion failures do not throw an appropriate exception for invalid arguments.

Example:

    /**
     * @throws ArithmeticException if divisor is zero
     */ 
    public void int divide(int divisor) {
        if (divisor == 0) {
            throw new ArithmeticException("Cannot divide by zero");
        }
        ...
    }

If you used an assertion here it could be turned off, and it would throw an AssertionFailedException, which is unhelpful and uninformative.


As it stands, the sentence you quoted is nonsense, I beleive.

To be sure, assert is not for validation of parameters.

But in every non-trivial program there are (or should be) a number of invariants, and this is the place where assertions may come in handy. If you can express the invariant in an assertion, please do so, no matter if the method is public or not.

Then, one of the following will happen:

a) everything is fine.
b) At runtime, the program fails with a non fulfilled assertion. If the assertion is correct, then the invariant is violated and you have the opportunity to find out why and fix the bug (or rethink your design).