Question is regarding assignment context of functional interface-
Predicate<String> p = String::isEmpty;
Works fine where the isEmpty
method declaration in String class is - public boolean isEmpty(){}
.
If I try to declare same in custom class like -
class Test{
public boolean isEmpty(){
...
}
}
And make same assignment -
Predicate<String> p = Test::isEmpty;
It would be compilation error -
The type Test does not define isEmpty(String) that is applicable here
And Predicate<T>
represents a predicate (boolean-valued function) of one argument and functional method is boolean test(T t){}
.
Any explanation? And am I missing anything?
You should have:
Predicate<Test> p = Test::isEmpty;
and not
Predicate<String> p = Test::isEmpty;
There is no String in
class Test {
public boolean isEmpty(){
...
}
}
so why should there be Predicate<String>
?
See the tutorial of method references. What you have here is the 3rd case "Reference to an instance method of an arbitrary object of a particular type".
Having
Predicate<String> p = String::isEmpty();
String s = "";
Calling p.test(s);
is the same as callign s.isEmpty();
so that's why you cannot give as argument a String
to call a method from Test
.
It would have been possible to have a common Predicate
if both String
and Test
would implement an interface Empty
with the method boolean isEmpty()
and then to have Predicate<Empty>
. Then both p.test(string)
and p.test(test)
would work; otherwise it won't, Java has strong typing and does not support duck typing.
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