Ответ 1
Я бы сказал, что блокировки Java 8 ( "Lambdas" ) не являются ни синтаксическим сахаром, ни являются первоклассными значениями.
Я рассмотрел проблему синтаксического сахара в ответе на другой вопрос StackExchange.
Что касается того, являются ли лямбда "первоклассниками", это действительно зависит от вашего определения, но я сделаю случай, когда лямбды не являются действительно первоклассными.
В некотором смысле лямбда хочет быть функцией, но Java 8 не добавляет типы функций. Вместо этого выражение лямбда преобразуется в экземпляр функционального интерфейса. Это позволило добавить lambdas в Java 8 с незначительными изменениями в системе типа Java. После преобразования результат является ссылкой, как и для любого другого ссылочного типа. Фактически, используя Lambda - например, в методе, который был передан лямбда-выражением в качестве параметра, неотличим от вызова метода через интерфейс. Метод, который получает параметр типа функционального интерфейса, не может определить, передано ли ему lambda-выражение или экземпляр некоторого класса, который реализует этот функциональный интерфейс.
Для получения дополнительной информации о том, являются ли лямбда объекты, см. Lambda FAQ Answer на этот вопрос.
Учитывая, что лямбды преобразуются в объекты, они наследуют (буквально) все характеристики объектов. В частности, объекты:
- имеют различные методы, такие как
equals
,getClass
,hashCode
,notify
,toString
иwait
- имеют хэш-код идентификации
- может быть заблокирован блоком
synchronized
- можно сравнить с помощью операторов
==
и!=
иinstanceof
и т.д. Фактически, все они не имеют значения для предполагаемого использования лямбда. Их поведение существенно undefined. Вы можете написать программу, которая использует любой из них, и вы получите какой-то результат, но результат может отличаться от версии для выпуска (или даже запускаться!).
Повторяя это более кратко, в Java объекты имеют идентичность, но значения (в частности, значения функций, если они должны существовать) не должны иметь понятия идентичности. Java 8 не имеет типов функций. Вместо этого лямбда-выражения преобразуются в объекты, поэтому у них есть большой багаж, который не имеет отношения к функциям, особенно к личности. Это не похоже на "первый класс" для меня.
Обновление 2013-10-24
Я уже думал об этой теме, так как уже несколько месяцев назад выложил свой ответ. С технической точки зрения все, что я написал выше, является правильным. Вывод, вероятно, выражен более точно, так как Java 8 lambdas не является чистым (в отличие от первоклассных) значений, поскольку они несут много предметного багажа. Однако только потому, что они нечистые, это не значит, что они не первоклассные. Рассмотрите определение Википедии первоклассной функции. Вкратце, критерии, перечисленные там для рассмотрения функций первого класса, - это способности:
- передать функции в качестве аргументов для других функций
- функции возврата из других функций
- назначать функции переменным
- хранить функции в структурах данных
- имеют функции анонимного
Java 8 lambdas соответствуют всем по этим критериям. Таким образом, это делает их первоклассными.
В статье также упоминаются имена функций, не имеющие специального статуса, вместо этого имя функции - это просто переменная, тип которой является типом функции. Java 8 lambdas не соответствуют этому последнему критерию. Java 8 не имеет типов функций; он имеет функциональные интерфейсы. Они используются эффективно, как типы функций, но они вообще не являются типами функций. Если у вас есть ссылка, тип которой является функциональным интерфейсом, вы не знаете, является ли она лямбдой, экземпляром анонимного внутреннего класса или экземпляром конкретного класса, который реализует этот интерфейс.
Таким образом, ямбады Java 8 являются более первоклассными функциями, чем я думал изначально. Они просто не являются чистыми первоклассными функциями.