I'm reading Effective Java Item 49. I am a bit confused about the example using assertion to validate params in private methods.
Some posts explained why we can use assertions in private because public methods are responsible for ensuring that the correct arguments are passed. So no risk to use assertion for the private methods.
But why don't we use Objects.requireNonNull
in private methods.
And since assertion can be turned off, why do we still use it in private, it won;t do validation if we don't enable it?
We need to unpick what you mean by "validation".
Case #1: If you are talking about internal consistency checks within your module, library or application, that you want to happen at test time, then assert
statements are an appropriate way to do that.
The kind of internal consistency checks that you might implement with assert
statements could be expensive. For instance you might "assert" that some invariant is true after each operation. This extra checking could well alter the computational complexity of operations when asserting checking is on. You don't want this kind of validation to happen in production.
Case #2: If you are talking about validation of external inputs to your application, using assert
is not the right way to do it. The main reason is that Java assertion checking can be turned off. Indeed, they routinely are turned off in production; see above for the reason. But you don't want validation of external (e.g. user) input to be turned off because that is liable to cause other problems such as bad data in your database, vulnerabilities, etc.
This kind of validation should not be done using assert
.
Case #3: Between those two cases above, we have the case where you are performing defensive validation on (say) parameters passed to some internal API within your code base.
assert
checks (i.e. the "test time" checks from case 1) to be turned on because they are liable to be expensive.So that means that you probably should not be using assert
for these tests either.
According to the above reasoning, it doesn't really make any difference if the methods in which you are doing the validation are public
, private
or something else. Using assert
or not is an orthogonal issue.
Finally, it is worth saying that many Java programmers avoid using the assert
statement entirely. A lot of the validation you would do using assert
at test time can also be done using mocking. By not using assert
at all, you avoid the scenario where someone creates performance problems for your application by turning on assertion checks in production!