Why when using an instance method in method reference (::
) does not throw a NullPointerException
if we set the Object instance to null?
public class MethodReferenceTest {
public static void main(String...strings){
PredicateSample predicateSample = new PredicateSample();
Predicate<String> predicate = predicateSample::isNotEmpty;
// NullpointerException ???
predicateSample = null;
Arrays.asList("a","b","c",null)
.stream()
.filter(predicate)
.forEach(System.out::println);
}
static class PredicateSample{
public boolean isNotEmpty(String s){
return ((s!=null) && (!s.isEmpty()));
}
}
}
It seems like predicateSample
is not invoked after constructing the Predicate?
The key line in the language spec is where it is discussing the runtime evaluation of method references (emphasis mine):
If the form is ExpressionName :: [TypeArguments] Identifier or Primary :: [TypeArguments] Identifier ...
- ....
- The target reference is the value of ExpressionName or Primary, as determined when the method reference expression was evaluated.
So it doesn't matter if you change the value of the target reference afterwards.
The method reference "remembered" the state of the predicateSample
when it was initialized. It has a reference exactly to that new PredicateSample()
you have created before.
After 2 lines executed, you have got two references to that new PredicateSample()
- the predicateSample
and the one "within" the method reference.
Changing the former makes no effect to the latter.
Let's do an interesting trick.
Here is an array to wrap up a new PredicateSample()
into a predicates[0]
:
PredicateSample[] predicates = new PredicateSample[1];
predicates[0] = new PredicateSample();
Within the lambda, you use a reference to the predicates[0]
;
Predicate<String> predicate = string -> predicates[0].isNotEmpty(string);
You update the predicates[0]
to null
and do the same stuff:
predicates[0] = null;
Stream.of("a","b","c").filter(predicate).forEach(System.out::println);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With