3

I was reading the Oracle documentation about using the assert keyword to verify method preconditions and postconditions.

The document says that it's fine to use the assert keyword to verify postconditions for public methods but you should only use the assert keyword to verify preconditions for private methods.

Why is this?

Dici
  • 25,226
  • 7
  • 41
  • 82
Ogen
  • 6,499
  • 7
  • 58
  • 124

2 Answers2

5

A complete answer instead of dumping it in comments.

Why shouldn't I use assertions for argument checking in public methods ?

Assertions relying on assert can be disabled by a JVM flag. Therefore, there's no way to guarantee assertions will indeed run when your users run your code. That's why it's bad to make promises to throw validation errors in your API if you can't actually guarantee it will happen. Therefore, you allow your users to call you with invalid parameters without throwing exceptions to warn them. You should use runtime exceptions instead.

So then, why is it fine to use it for post-conditions in public methods ?

The doc you quoted defines pre and post conditions as follows:

Preconditions — what must be true when a method is invoked. Postconditions — what must be true after a method completes successfully.

You can see that pre-conditions depend on the caller while post-conditions depend on the callee. If pre-conditions were met, the only reason why a post-condition could fail is because the code in the method is buggy. It isn't a user mistake, it's a problem with the library itself. I'm guessing that's why the doc believes it's less problematic to end up with disabled post-conditions assertions.

I'm not sure I personally agree because if post-conditions are not met it probably means the contract of the method has been violated and execution should stop. Depends how critical the post-condition was. API writers may want to check some ratio is optimal for performance at the end of a dynamic array resize, but not necessarily throw an exception if it was not the case as the program would still behave as expected even with a sub-optimal ratio.

Dici
  • 25,226
  • 7
  • 41
  • 82
4

You should be checking the arguments to your public functions in all cases. If assert is disabled, then this kind of checking will not get done if it is implemented via assert.

Joe C
  • 15,324
  • 8
  • 38
  • 50
  • I'm asking why it's okay to verify postconditions in public methods but not preconditions. I'm still confused I don't think my question has been answered. – Ogen Nov 12 '17 at 23:09
  • 2
    @Ogen assertions relying on `assert` can be disabled by a JVM flag. Therefore, there's no way to guarantee assertions will indeed run when your users run your code. That's why it's bad to make promises to throw validation errors in your API if you can't actually guarantee it will happen. You should use runtime exceptions instead. – Dici Nov 12 '17 at 23:11
  • Okay so you're saying that assertions should not be used as a substitute for argument checking in public methods because the caller may have assertions turned off - in which case, your assertion checks will not run. If that's the case, why should you use assertions to verify postconditions in public methods at all? Why not just use standard argument checking there too? – Ogen Nov 12 '17 at 23:15
  • 1
    @Ogen I don't believe seeing that in the doc, but I didn't read everything. I'd say assertions are not suited for any public runtime check. To be honest, the errors they generate are not as good as exceptions so I wouldn't personally recommend them in any context – Dici Nov 12 '17 at 23:17
  • @Dici I understand this is an opinionated matter. But the oracle documentation makes it clear that you can use assert for public postconditions and private preconditions. Their usefulness is out of the scope of this question I think. – Ogen Nov 12 '17 at 23:19
  • @Ogen I tried to condense my previous answers as well as a personal interpretation of the doc concerning post-conditions in a single proper answer. Take a look and feel free to comment, I'll iterate as needed – Dici Nov 12 '17 at 23:34