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