Присвоение объекта переменной интерфейса без реализации интерфейса - PullRequest
0 голосов
/ 16 мая 2018

Я только что узнал о концепции ссылки на метод в java 8. То, что я нашел странным, - это пример, когда ссылка на метод присваивается переменной интерфейса без реализации интерфейса, а вызов абстрактного метода интерфейса вызывает метод, на который ссылаются.

interface Sayable {
    void say();
}

public class InstanceMethodReference {
    public void saySomething() {
        System.out.println("Hello, this is non-static method.");
    }

    public static void main(String[] args) {
        InstanceMethodReference methodReference = new InstanceMethodReference();
        Sayable sayable = methodReference::saySomething;
        sayable.say();
    }
}

Выше кода печатается сообщение метода saySomething, я пытаюсь понять, как здесь выполняется распределение памяти для методов и объектов и как это в целом работает.

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Хотя ваш Sayable явно не объявляет, что это @FunctionalInterface, он действительно один, поскольку у него ровно один нестатический метод.

Любому функциональному интерфейсу может быть назначен лямбда-как выражение (например, () -> printf("bla bla")) или ссылка на метод (например, methodReference::saySomething).Вот и все.

0 голосов
/ 16 мая 2018

Это просто синтаксический сахар для анонимной реализации или лямбда с закрытием (ссылаясь на состояние вне определения, в вашем случае экземпляр methodReference). Ссылки на методы и лямбды обрабатываются одинаково в этом отношении. Так что такое же распределение памяти на самом деле.

Использование ссылок на методы (или лямбды) возможно, когда в интерфейсе есть только один нестатический метод , и сигнатура этого метода совпадает с сигнатурой лямбды или ссылки на метод. В этом случае компилятор будет знать, как обернуть его, и поэтому он будет назначаться. Не имеет значения, является ли это одним из «стандартных» интерфейсов, таких как Function, Consumer или Supplier или пользовательским, это должен быть функциональный интерфейс, вот и все.

Ниже цитируется из официальной документации Oracle по Java :

Arrays.sort(rosterAsArray, Person::compareByAge);

Ссылка на метод Person::compareByAge семантически совпадает с лямбда-выражением (a, b) -> Person.compareByAge(a, b). Каждый имеет следующие характеристики:

  • Его список формальных параметров скопирован с Comparator.compare, который (Person, Person).
  • Его тело вызывает метод Person.compareByAge.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...