Подтвердить что ты не робот

Почему компиляция эталонного задания метода?

Я пытаюсь понять, почему компилируется следующий код:

public class MethodRefs {

    public static void main(String[] args) {
        Function<MethodRefs, String> f;

        f = MethodRefs::getValueStatic;

        f = MethodRefs::getValue;
    }

    public static String getValueStatic(MethodRefs smt) {
        return smt.getValue();
    }

    public String getValue() {
        return "4";
    }

}

Я вижу, почему первое присваивание действительно - getValueStatic явно соответствует указанному типу Function (он принимает объект MethodRefs и возвращает String), но второй меня озаряет - getValue метод не принимает аргументов, так почему все еще допустимо назначить его f?

4b9b3361

Ответ 1

Второй

f = MethodRefs::getValue;

совпадает с

f = (MethodRefs m) -> m.getValue();

Для нестатических методов всегда существует неявный аргумент, который представлен как this в вызываемом.

ПРИМЕЧАНИЕ. Реализация немного отличается на уровне байтового кода, но она делает то же самое.

Ответ 2

Нестатический метод по существу берет ссылку this как особый аргумент. Обычно этот аргумент написан особым образом (перед именем метода, а не в круглых скобках после него), но концепция одинаков. Метод getValue принимает объект MethodRefs (его this) и возвращает строку, поэтому он совместим с интерфейсом Function<MethodRefs, String>.

Ответ 3

Немного скорректирует его:

import java.util.function.Function;

public class MethodRefs {

  public static void main(String[] args) {
    Function<MethodRefs, String> f;


    final MethodRefs ref = new MethodRefs();

    f = MethodRefs::getValueStatic;
    f.apply(ref);
    //is equivalent to 
    MethodRefs.getValueStatic(ref);

    f = MethodRefs::getValue;
    f.apply(ref);
    //is now equivalent to 
    ref.getValue();
  }

  public static String getValueStatic(MethodRefs smt) {
    return smt.getValue();
  }

  public String getValue() {
    return "4";
  }
}

Ответ 4

В учебнике по Java объясняется, что существует 4 различных типа ссылок на методы:

Ваш случай равен # 3, что означает, что если у вас есть экземпляр MethodRef i.e. ref, вызов apply в вашей функции f будет эквивалентен String s = ref.getValue().

Ответ 5

Для нестатических методов тип this считается неявным как первый тип аргумента. Так как тип типа MethodRefs, типы проверяются.