我一直在使用Java 8功能接口,当我开始执行以下代码时,我发现了一些不寻常的事情。
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.
}
}
如您所见,静态方法process(List<String> names, Carnivore c)
的对象类型为Carnivore
。方法调用process(fnames, TestClass::size )
有效,并且没有编译时错误,这怎么可能?我无法理解此方法调用在内部如何工作。我期待有一个错误,因为TestClass
不是Carnivore
。
我找到的最佳答案:“您可以显式传递Carnivore
实例,也可以传递对与Carnivore抽象方法eat(List<String> foods)
的参数列表相匹配的方法的引用”
pass a reference to a method that matches the parameter list of abstract method
部分让我感到困惑。
感谢专家们帮助我理解调用process(fnames, TestClass::size );
时会发生什么。
答案 0 :(得分:3)
Carnivore
是具有单个抽象方法int eat(List<String> foods);
的功能接口。
因此,可以使用适合eat
方法签名的任何方法来实现该接口。
public static int size(List<String> names)
是这样的方法,因为它接受一个List<String>
参数并返回一个int
。因此,TestClass::size
可以作为类型Carnivore
的参数传递,这就是process(fnames, TestClass::size);
传递编译的原因。
顺便说一句,Tiger
不必为Carnivore
实现process(fnames, t::eat);
接口来传递编译,因为public int eat(List<String> foods)
方法还与功能接口的单个摘要的签名匹配。方法。