将"pass a reference"传递给匹配抽象方法参数列表的方法时,java 8如何在内部求值?

How java 8 evaluates internally when passing "pass a reference" to a method that matches the parameter list of abstract method?

我一直在使用 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.

我找到的最佳答案:"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)"

pass a reference to a method that matches the parameter list of abstract method 部分让我感到困惑。

感谢专家帮助我理解调用 process(fnames, TestClass::size ); 时会发生什么。

Carnivore 是一个函数式接口,只有一个抽象方法 int eat(List<String> foods);.

因此,任何符合eat方法签名的方法都可以用来实现接口。

public static int size(List<String> names) 就是这样一种方法,因为它需要一个 List<String> 参数和 returns 一个 int。因此 TestClass::size 可以作为类型 Carnivore 的参数传递,这就是 process(fnames, TestClass::size); 通过编译的原因。

顺便说一句,Tiger 不必为 process(fnames, t::eat); 实现 Carnivore 接口来通过编译,因为 public int eat(List<String> foods) 方法也匹配功能接口的签名单个抽象方法。