Пропускают ли ссылки на методы накладные расходы на лямбда-оболочку? Могут ли они в будущем?
Согласно Учебному руководству по Java о методах :
Иногда ... лямбда-выражение делает только вызов существующего метода. В этих случаях часто проще обратиться к существующему методу по имени. Ссылки на методы позволяют вам сделать это; это компактные, легко читаемые лямбда-выражения для методов, которые уже имеют имя.
Я предпочитаю лямбда-синтаксис синтаксису ссылки на метод по нескольким причинам:
Лямбды понятнее
Несмотря на заявления Oracle, я нахожу лямбда-синтаксис более легким для чтения, чем сокращенная ссылка на метод объекта, поскольку синтаксис ссылки на метод неоднозначен:
Bar::foo
Вы вызываете статический метод с одним аргументом для класса x и передаете его x?
x -> Bar.foo(x)
Или вы вызываете метод экземпляра с нулевым аргументом для x?
x -> x.foo()
Синтаксис ссылки на метод может заменять любой из них. Он скрывает то, что на самом деле делает ваш код.
Лямбды безопаснее
Если вы ссылаетесь на Bar :: foo как на метод класса, а Bar позже добавляет метод экземпляра с тем же именем (или наоборот), ваш код больше не будет компилироваться.
Вы можете использовать лямбды последовательно
Вы можете обернуть любую функцию в лямбду - так что вы можете использовать один и тот же синтаксис везде. Синтаксис ссылки на метод не будет работать с методами, которые принимают или возвращают примитивные массивы, генерируют проверенные исключения или имеют то же имя метода, которое используется в качестве экземпляра, и статический метод (поскольку синтаксис ссылки на метод неоднозначен в отношении того, какой метод будет вызван) , Они не работают, когда вы перегружаете методы с одинаковым количеством аргументов, но вы все равно не должны этого делать (см. Пункт 41 Джоша Блоха), поэтому мы не можем отнести это к ссылкам на методы.
Заключение
Если за это не снижается производительность, у меня возникает соблазн отключить предупреждение в моей среде IDE и последовательно использовать лямбда-синтаксис, не добавляя случайную ссылку на метод в мой код.
PS
Ни здесь, ни там, но в моих снах ссылки на методы объекта выглядят больше так и применяют invoke-dynamic к методу непосредственно к объекту без лямбда-обертки:
_.foo()
.map(_.acceptValue())
Если я не ошибаюсь, это очень похоже на синтаксис Scala. Может быть, вы просто пытаетесь использовать не тот язык.
System.out::println
чтобы forEach()
все время ...?