Собирается ли введение новой лямбда-нотации (см., Например, эту статью ) в Java 8 какого-либо вывода типа?
Если да, то как новая система типов повлияет на язык Java в целом?
источник
Собирается ли введение новой лямбда-нотации (см., Например, эту статью ) в Java 8 какого-либо вывода типа?
Если да, то как новая система типов повлияет на язык Java в целом?
В ответе фаната трещоток и в ветке комментариев есть немало неверной информации . Я отвечу здесь в ответе, так как комментарий слишком мал. Кроме того, так как это ответ в конце концов, я попытаюсь ответить и на оригинальный вопрос. (Обратите внимание, что я не эксперт по системам типов.)
Во-первых, краткими ответами на первоначальный вопрос являются «Да» и «Нет». Да, в Java 8 будет значительно больше выводов типов, чем в Java 7, и «Нет», в Java 8 нет «новой» системы типов, хотя есть некоторые небольшие изменения. ,
Java 8 по-прежнему будет статически типизированной, и у нее все еще будет дихотомия между классами и интерфейсами. Нет новых типов, таких как типы функций. Тип лямбды - это, по сути, «функциональный интерфейс», который представляет собой обычный интерфейс с одним абстрактным методом.
Интерфейсы теперь могут иметь код в виде методов по умолчанию, но модель одиночного наследования классов и множественного наследования интерфейсов остается прежней. Конечно, есть некоторые корректировки, такие как правила разрешения методов при наличии методов по умолчанию, но основные принципы не изменились.
Любой тип, который определяется выводом типа, может быть записан явно. Чтобы использовать пример с трещоткой ,
Collections.<MyClass>sort(list, (a, b) -> { return a.order - b.order; });
в основном сахар для
Collections.<MyClass>sort(list,
(Comparator<MyClass>)((MyClass a, MyClass b) -> { return a.order - b.order; }));
Так sparkleshy «s заявление„умозаключение типа не требует какого - либо расширения системы типа“в основном правильно.
Но чтобы вернуться к синтаксическому сахару, я повторю свое утверждение, что лямбда-выражение не является синтаксическим сахаром для анонимного внутреннего класса. Чокнутый Ratchet заявил, что лямбда-выражение транслируется в создание экземпляра анонимного внутреннего класса, и Спарклеши просто подтвердил, что лямбда является синтаксическим сахаром для анонимного внутреннего класса, но эти утверждения неверны. Вероятно, они основаны на устаревшей информации. Ранние лямбда-реализации действительно реализовывали лямбды таким образом, но все изменилось.
Лямбда-выражения семантически отличаются от внутренних классов и реализуются иначе, чем внутренние классы.
Лямбда-выражения семантически отличаются от внутренних классов несколькими способами. Оценка лямбда-выражения не должна каждый раз создавать новый экземпляр. Они также имеют различную семантику захвата, например, они фиксируют это по- разному. Во внутреннем классе, это является экземпляр внутреннего класса, в то время как в лямбда, это является экземпляр вшита. Учтите следующее:
public class CaptureThis {
void a(Runnable r) { r.run(); }
void b() {
a(new Runnable() { public void run() { System.out.println(this); }});
a(() -> System.out.println(this));
}
public String toString() { return "outer"; }
public static void main(String[] args) { new CaptureThis().b(); }
}
В недавней лямбда-сборке JDK 8 (я использовал b69 ) вывод будет примерно таким:
CaptureThis$1@113de03
outer
Кроме того, лямбда-выражения реализованы совершенно иначе, чем внутренние классы. Если вы сравните дизассемблированный вывод, то увидите, что код внутреннего класса напрямую компилируется с созданием и вызывает конструктор CaptureThis $ 1, тогда как лямбда-выражение компилируется в вызываемую динамическую инструкцию, которая получает Runnable через, означает неопределенное. Полное объяснение того, как это работает и почему, см. В докладе Брайана Гетца «JavaOne 2012», « Лямбда: взгляд под капотом» .
this
наMyClass.this