* Do not use assertions for argument checking in public methods.
Argument checking is typically part of the published specifications (or contract) of a method, and these specifications must be obeyed whether assertions are enabled or disabled. Another problem with using assertions for argument checking is that erroneous arguments should result in an appropriate runtime exception (such as IllegalArgumentException, IndexOutOfBoundsException, or NullPointerException). An assertion failure will not throw an appropriate exception.
I also think there will be less bugs and that debugging will be easier if the contract is checked and a fast explicit failure results from a breach of contract
...the fact that a contract exists on paper doesn't mean anything unless you enforce it...
Specifying the contract of a method is not about returning a value for every conceivable input value...
anyone reading it can expect an AssertionError as soon as they violate the contract of the method: they know immediately when they do so. (Note that expecting it and relying on it are different things. If they catch the AssertionError, all bets are off: in production code you'd get badness).
If you truly do want to be able to handle every possible argument from callers, including nulls, etc, then your method should not throw an exception at all for those cases, but instead respond in a predictable fashion (return a defined value, for instance, like null). If you do not care to support those cases, then simply declare the preconditions callers must meet before passing args into your method, and from that point you may assume they are true without checking. (It doesn't hurt, by the way, to assert preconditions at the beginning of a method and postconditions just before returning--that's actually what asssertions were invented for...but keep in mind these are designed to be turned off at deployment time so no one should be depending upon them.
the real value of contracts is in setting expectations and drawing boundaries of responsibility