Лямбда-выражения не меняют набор проблем, которые вы можете решить с помощью Java в целом, но определенно упрощают решение определенных проблем, по той же причине, по которой мы больше не программируем на языке ассемблера. Удаление избыточных задач из работы программиста облегчает жизнь и позволяет делать то, чего вы даже не трогали бы в противном случае, просто за тот объем кода, который вам пришлось бы создать (вручную).
Но лямбда-выражения - это не просто сохранение строк кода. Лямбда-выражения позволяют определять функции , для которых раньше вы могли использовать анонимные внутренние классы в качестве обходного пути, поэтому вы можете заменить анонимные внутренние классы в этих случаях, но не в целом.
В частности, лямбда-выражения определяются независимо от функционального интерфейса, в который они будут преобразованы, поэтому нет унаследованных членов, к которым они могли бы получить доступ, кроме того, они не могут получить доступ к экземпляру типа, реализующего функциональный интерфейс. В лямбда-выражении this
и super
имеют то же значение, что и в окружающем контексте, см. Также этот ответ . Кроме того, вы не можете создавать новые локальные переменные, скрывающие локальные переменные окружающего контекста. Для предполагаемой задачи определения функции это удаляет множество источников ошибок, но также подразумевает, что для других случаев использования могут существовать анонимные внутренние классы, которые нельзя преобразовать в лямбда-выражение, даже если реализуется функциональный интерфейс.
Кроме того, конструкция new Type() { … }
гарантирует создание нового отдельного экземпляра (как new
всегда). Экземпляры анонимного внутреннего класса всегда сохраняют ссылку на свой внешний экземпляр, если они созданы вне static
контекста. Напротив, лямбда-выражения захватывают ссылку только this
тогда, когда это необходимо, то есть если они обращаются this
или не являются static
членами. И они создают экземпляры намеренно неуказанной идентичности, что позволяет реализации решать во время выполнения, следует ли повторно использовать существующие экземпляры (см. Также « Создает ли лямбда-выражение объект в куче каждый раз при выполнении? »).
Эти различия относятся к вашему примеру. Конструкция вашего анонимного внутреннего класса всегда будет создавать новый экземпляр, а также может захватывать ссылку на внешний экземпляр, тогда как ваше (Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName())
лямбда-выражение без захвата, которое в типичных реализациях будет оцениваться как одноэлементное. Кроме того, он не производит.class
файл на вашем жестком диске.
Учитывая различия, касающиеся как семантики, так и производительности, лямбда-выражения могут изменить способ решения программистами определенных проблем в будущем, конечно, также из-за новых API, охватывающих идеи функционального программирования с использованием новых функций языка. См. Также лямбда-выражение Java 8 и первоклассные значения .
(o1, o2) -> o1.getName().compareTo(o2.getName())