Почему компиляция эталонного задания метода?
Я пытаюсь понять, почему компилируется следующий код:
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
?
Ответы
Ответ 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
, типы проверяются.