RFR 9: 8138963 : java.lang.Objects new method to default to non-null (original) (raw)
John Rose john.r.rose at oracle.com
Sat Oct 31 19:44:31 UTC 2015
- Previous message: RFR 9: 8138963 : java.lang.Objects new method to default to non-null
- Next message: RFR 9: 8138963 : java.lang.Objects new method to default to non-null
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Oct 31, 2015, at 4:17 AM, Remi Forax <forax at univ-mlv.fr> wrote:
Hi John, I think there is a good reason to not reuse/enhance the requireNonNull prefix, requireNonNull here is used to check a precondition or an invariant (a contract), hence a name that starts with 'require' like in Eiffel. (BTW re-reading this thread, Brian already said that)
Ah, of course—that's where require came from, from contract terms. Thanks.
requireNonNullElseGet is not something that checks a contract and as you said, nonNull is not a good prefix too, so we should starts a new family.
It seems to me that, even so, "require*" makes excellent logical sense for the proposed use case. As I said, it requires a slight adjustment (really, an expansion) of the contract viewpoint. I think we should be happy to think of the new "require*" logic as an "extended contract" or "contract with fallback/repair".
Why shouldn't contract checks (at least in our system) offer repairs? Why must "require", as imported from Eiffel (or some such place) dictate the meaning of a family of Java methods? If I am working on new Java code, and I want to enforce a dynamically checked condition P on some value X, I first think, "X must be (is required to be) P", and then as a secondary thought I think, "what event E should happen if that fails?" In this case, X is a reference value and P is "must not be null". E can often be:
- throw NullPointerException
- throw IllegalArgumentException
- throw AssertionError (use assert syntax)
- replace X with an ad hoc fallback value
- replace X with the result of some ad hoc computation (Supplier.get)
- execute some ad hoc logic inline (control flow)
I understand that contract systems (per se) allow a single contract to be injected across a range of sites, and so the use of ad hoc local values is impossible in those use cases, but (again) we are not designing a contract system here.
— John
P.S. If we did add a contract system, perhaps we would end up with double-requires, as:
class Box { private T value; static require { Objects.requireNonNull(value); } // value null-checked before every storage ... }
This suggests there is only a weak linkage between some hypothetical contract system and the present API.
P.P.S.
what about: T coalesceNull(T, T) T coalesceNullGet(T, Supplier<? extends T>)
(Sorry, not for my bikeshed.)
- Previous message: RFR 9: 8138963 : java.lang.Objects new method to default to non-null
- Next message: RFR 9: 8138963 : java.lang.Objects new method to default to non-null
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]