For the following declaration
public static <E extends SomeInterface> E methodName(
@NonNull Supplier<@NonNull E> supplier,
Consumer<@NonNull E> consumer)
does Lombok automatically null-check the supplier
s result ?
And/or does it make it make sense for the consumer
to ensure that the E passed in is null-checked (e.g. by generating a null wrapper)?
As per the docs, @NonNull
is purely documentary, except for 2 cases:
That is it. Lombok does not generate any checks if you stick it on a method / on a return type, for example.
This is intentional, and any PRs to change this behaviour would be denied. (SOURCE: I'm one of the 2 people who makes the final call on such things).
To explain specifically why lombok does not and in fact cannot do anything meaningful to @NonNull
within <>
:
Imagine you have a method taking an Iterable<String>
.
What do you expect lombok to do? Call .iterator()
on the parameter, loop through to the end (keep iterating until hasNext()
returns false
), and report if any .next()
call returns null
? This:
requires knowing how Iterable
works. Lombok cannot encode the sum total knowledge of the entire java ecosystem. At best we can hardcode that we 'know' what the generics mean for well known types and just give up on anything else. And then, I guess, write some sort of plugin system so you can check your own stuff? This is a herculean and complicated affair for.. what, exactly?
Simply does not work here - you can make iterables that are literally infinite. Lombok would encode an endless loop, in a way that isn't obvious. Obviously highly undesired behaviour.
Literally mathematically impossible. Imagine a Supplier<@NonNull String>
. Do we just call it 50 times, check for null
, and consider 'good enough' after 50 loops? What about a IntFunction<@NonNull String>
. Do we invoke it with all 4 billion possible int
values? What about Function<String, @NonNull String>
? What if this function isn't 'stable'? The docs of Function
do not require that it is - what if invoking it with some value the first time produces a different result from the second time?
At best lombok can add null checks when you invoke your lambdas inside that method. But this doesn't actually prove much. What if you hand this lambda off to another method? For 'normal' nullity annotations (directly on a parameter), the @NonNull
guarantees it's right and this guarantee survives passing the variable around. This simply isn't possible with generics.