I have been working with java 8 functional interfaces and I noticed something unusual when I started executing below code.
interface Carnivore{
default int calories( List<String> food)
{
System.out.println("=======line ABC ");
return food.size() * 100;
}
int eat(List<String> foods);
}
class Tiger implements Carnivore{
public int eat(List<String> foods)
{
System.out.println("eating "+ foods);
return foods.size();
}
}
public class TestClass {
public static int size(List<String> names){
System.out.println("======line XYZ ");
return names.size()*2;
}
public static void process(List<String> names, Carnivore c){
c.eat(names);
}
public static void main(String[] args) {
List<String> fnames = Arrays.asList("a", "b", "c");
Tiger t = new Tiger();
process(fnames, t::eat);
process(fnames, t::calories);
process(fnames, TestClass::size ); // ----> this is where I am confused.
}
}
As you can see that static method process(List<String> names, Carnivore c)
takes object type Carnivore
. The method call process(fnames, TestClass::size )
works, and there's no compile time error, how is this possible? I'm not able to comprehend how internally this method call works. I was expecting an error because TestClass
is not Carnivore
.
The best answer I found: "You can either pass a Carnivore
instance explicitly or pass a reference to a method that matches the parameter list of Carnivore's abstract method eat(List<String> foods)
"
The part pass a reference to a method that matches the parameter list of abstract method
is confusing to me.
Appreciated if experts help me understand what happens when process(fnames, TestClass::size );
is called.
Carnivore
is a functional interface having a single abstract method int eat(List<String> foods);
.
Therefore, any method that fits the signature of the eat
method can be used to implement the interface.
public static int size(List<String> names)
is such a method, since it takes a List<String>
argument and returns an int
. Therefore TestClass::size
can be passed as an argument of type Carnivore
, which is why process(fnames, TestClass::size);
passes compilation.
BTW, Tiger
does not have to implement the Carnivore
interface for process(fnames, t::eat);
to pass compilation, since the public int eat(List<String> foods)
method also matches the signature of the functional interface's single abstract method.