Как Java 8 оценивает внутренне при передаче «передать ссылку» методу, который соответствует списку параметров абстрактного метода? - PullRequest
0 голосов
/ 24 октября 2018

Я работал с функциональными интерфейсами 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, либо передать ссылку на метод, который соответствуетсписок параметров абстрактного метода Хищника eat(List<String> foods) "

Часть pass a reference to a method that matches the parameter list of abstract method смущает меня.

Ценится, если эксперты помогут мне понять, что происходит, когда вызывается process(fnames, TestClass::size );.

1 Ответ

0 голосов
/ 24 октября 2018

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) также соответствует сигнатуре единственного абстрактного метода функционального интерфейса.

...