I have an interface and its parameter can be null
.
int count(@Nullable F filter);
To avoid null
parameters and null-checks, common advice is to use the method overloading:
int count();
int count(@NonNull F filter);
In some cases, I don't like this approach, because it forces clients to make this kind of job:
F f = getFilter();
int count = f != null ? count(f) : count();
It much more convenient for client to use:
count(getFilter())
Optionals, at the first glance, can solve this problem but Optional
should not be used for parameters https://rules.sonarsource.com/java/RSPEC-3553
So my question is: can I use Supplier
instead?
// service code:
int count(Supplier<F> filter) {
Optional.ofNullable(filter.get()).map(f -> count(f)).orElseGet(() -> count());
};
//client code:
count(() -> getFilter())
Or even
int count(Supplier<Optional<F>> filter)
Idea doesn't show any warnings.
I personally like my code after that, but isn't it cheating? Why it's better than Optional
?
EDIT: Thanks for comments. I agree, in my case Supplier
is just a sophisticated @Nullable
approach.
I will return to:
int count();
int count(@NonNull F filter);
/////
getFilter().map(f -> count(f)).orElseGet(() -> count());
CodePudding user response:
If you don't want the client-code to dial with null
, you can change the method getFilter()
to return Optional<F>
.
In this case, the code in the client would look like that:
int count = getFilter().map(MyClass::count).orElse(MyClass.count());
With this approach, your method count(F)
doesn't require any extra logic.
If it feels like too complicated, then can implement count(F)
in such a way that it would delegate to count()
in case if provided argument is null
.
Both your attempt with Supplier<F>
and Supplier<Optional<F>>
are artificial and seem to be driven by intention to circumvent Sonar, rather than by the real use cases.