В Java 8 появилась новая реклама с долгожданными лямбда-выражениями; каждые 3 дня появляется новая статья о том, как они круты.
Насколько я понял, лямбда-выражение - это не что иное, как анонимный внутренний класс с одним методом (по крайней мере, на уровне байт-кода). Помимо этого он имеет еще одну приятную особенность - вывод типа, но я считаю, что эквивалент этого можно достичь с помощью обобщений на некотором уровне (конечно, не таким аккуратным способом, как с лямбда-выражениями).
Зная это, принесут ли лямбда-выражения нечто большее, чем просто синтаксический подсахаринг в Java? Могу ли я создать более мощные и гибкие классы или другие объектно-ориентированные конструкции с лямбда-выражениями, которые невозможно построить с использованием текущих возможностей языка?
источник
this
вOuterClass.this
- это часть процесса удаления лямбда-выражений в анонимном классе.Ответы:
tl; dr: хотя это в основном синтаксический сахар, этот более приятный синтаксис делает множество практических вещей, которые заканчивались бесконечными, нечитаемыми строками скобок и скобок.
Ну, на самом деле все наоборот, поскольку лямбды намного старше, чем Java. Внутренние анонимные классы с одним методом являются (были) наиболее близкими к лямбдам Java. Это приближение, которое было «достаточно хорошим» в течение некоторого времени, но имеет очень неприятный синтаксис.
На первый взгляд, лямбды Java 8 кажутся не чем иным, как синтаксическим сахаром, но когда вы смотрите под поверхность, вы видите множество интересных абстракций. Например, спецификация JVM трактует лямбду совершенно иначе, чем «истинный» объект, и хотя вы можете обрабатывать их так, как если бы они были объектами, JVM не обязана реализовывать их как таковые.
Но в то время как все эти технические хитрости интересны и актуальны (поскольку они позволяют в будущем оптимизировать JVM!), Реальным преимуществом является «просто» синтаксическая часть сахара.
Что легче читать:
или:
или (используя дескриптор метода вместо лямбды):
Тот факт, что вы, наконец, можете выразить в сжатой форме, которая раньше была бы 5 строками кода (из которых 3 очень скучные), приносит реальное изменение того, что практично (но не того, что возможно, само собой разумеющееся).
источник
List
может содержать любой объект,List<String>
может «только» содержать строки. Обобщения добавили ограничение (и возможность формализовать ограничения!), А не добавление к власти. Почти все, что с тех пор, как Java 1.1 стала синтаксическим сахаром. И это не обязательно плохо.List<String>
- это простоList
приведение кString
некоторым возвращаемым значениям. Тем не менее, они чрезвычайно полезны и сделали язык намного более удобным для написания. Лямбды похожи.Да, для Java это не что иное, как лучший способ создания анонимного внутреннего класса. Это из-за фундаментального решения в Java, что каждый бит байтового кода должен жить в определенном классе, который не может быть изменен сейчас после десятилетий унаследованного кода.
Однако это не то, о чем на самом деле говорят лямбда-выражения. В формализмах, где они являются нативными понятиями, а не искривлением "скачка на поводке", лямбды являются фундаментальными строительными блоками; и их синтаксис, и отношение людей к ним очень разные. Пример анонимной рекурсивной функции, созданной исключительно из лямбд в Структуре и интерпретации компьютерных программ , способен изменить всю вашу концепцию вычислений. (Тем не менее, я совершенно уверен, что способ научиться программировать - это просто эзотерика, чтобы стать историей успеха.)
источник
Да, это просто синтаксический сахар, в том смысле, что где бы вы ни писали лямбду, вы можете переписать это выражение как анонимное выражение внутреннего класса с помощью одного метода, где класс реализует функциональный интерфейс, выведенный для контекста лямбды, и это было бы точно эквивалентно семантически. И вы можете сделать это, просто заменив лямбда-выражение анонимным выражением класса, не изменяя любое другое выражение или строку кода.
источник
this
его нужно будет преобразовать вOuterClass.this
. Это не противоречит тому, что я сказал - каждое лямбда- выражение может быть преобразовано в семантически эквивалентное выражение анонимного класса, не изменяя ничего вне этого выражения . Я не говорил, что внутренняя часть не изменится.this
лямбда является частью синтаксического сахара и не является разницей в семантике. И о различиях в реализации, реализации! = Семантика. О различиях в идентичности объекта; идентичность объекта чрезвычайно касательна к функциональности лямбд; в любом случае никто не проверяет объектную идентичность классов lambdas / anon, потому что это бесполезно.Йоахим Зауэр уже хорошо поработал, отвечая на ваш вопрос, но только намекнул на то, что я считаю важным. Поскольку лямбды не являются классами, они также не компилируются как таковые. Все анонимные внутренние классы приводят к созданию файла .class, который, в свою очередь, должен быть загружен ClassLoader. Таким образом, использование Lambdas вместо этого не только делает ваш код более красивым, но также уменьшает размер вашего скомпилированного кода, объем памяти вашего ClassLoader и время, необходимое для передачи битов с вашего жесткого диска.
источник
Нет, они не.
Иными словами, лямбда-выражения - это не объектно-ориентированный, хотя и лаконичный способ достижения того же, чего достиг бы анонимный класс или, по моему предпочтению, внутренний класс объектно-ориентированным способом.
источник