Абстрактный класс как функциональный интерфейс

В Java 8 абстрактный класс только с одним абстрактным методом не является функциональным интерфейсом (JSR 335 ).

Этот interface представляет собой функциональный интерфейс:

public interface MyFunctionalInterface {
    public abstract void myAbstractMethod();
    public default void method() {
        myAbstractMethod();
    }
}

но это abstract class не:

public abstract class MyFunctionalAbstractClass {
    public abstract void myAbstractMethod();
    public void method() {
        myAbstractMethod();
    }
}

Поэтому я не могу использовать абстрактный класс в качестве цели для лямбда-выражений и ссылок на методы.

public class Lambdas {
    public static void main(String[] args) {
        MyFunctionalAbstractClass functionalAbstractClass = () -> {};
    }
}

Ошибка компиляции: The target type of this expression must be a functional interface.

Почему разработчики языка наложили это ограничение?


person gontard    schedule 07.07.2014    source источник
comment
Хороший вопрос... может совместимость?   -  person Mena    schedule 07.07.2014
comment
Об этом уже спрашивали и отвечали... основная причина - гибкость в будущем, когда ожидается, что лямбда-выражения будут сильно отличаться от экземпляров класса.   -  person Marko Topolnik    schedule 07.07.2014
comment
Вот, прочитайте из первых уст .   -  person Marko Topolnik    schedule 07.07.2014
comment
@MarkoTopolnik Опубликуйте краткое резюме и эту ссылку в качестве ответа. Я просто ненавижу видеть вопросы без ответов с ответами в комментариях. :-)   -  person Stuart Marks    schedule 07.07.2014
comment
@StuartMarks Да, вы правы. Готово.   -  person Marko Topolnik    schedule 07.07.2014


Ответы (1)


Это была важная тема с самого начала проекта Lambda, и над ней много думали. Брайан Гетц, главный архитектор языка Java, решительно поддерживает представление о лямбда-выражениях как о функции, а не объекте. Цитировать:

Я считаю, что лучшим направлением развития Java является поощрение более функционального стиля программирования. Роль Lambda в первую очередь заключается в поддержке разработки и использования более функциональных библиотек.

Я с оптимизмом смотрю в будущее Java, но чтобы двигаться вперед, нам иногда приходится отказываться от некоторых удобных идей. Лямбда-функции открывают двери. Lambdas-are-objects закрывает их. Мы предпочитаем, чтобы эти двери оставались открытыми.

Здесь ссылка на источник цитаты и здесь находится более поздняя запись Брайана, в которой повторяется те же философские моменты и подтверждает их дополнительными, более практическими аргументами:

Упрощение модели открывает двери для всевозможных оптимизаций виртуальных машин. (Ключевой здесь является отказ от идентичности.) Функции — это значения. Моделирование их как объектов делает их более тяжелыми и сложными, чем они должны быть.

Прежде чем бросить этот вариант использования под автобус, мы провели анализ корпуса, чтобы выяснить, как часто используются SAM абстрактного класса по сравнению с интерфейсными SAM. Мы обнаружили, что в этом корпусе только 3% экземпляров внутренних классов-кандидатов на лямбда-выражения имели своей целью абстрактные классы. И большинство из них поддавались простому рефакторингу, когда вы добавляли конструктор/фабрику, которая принимала лямбду, ориентированную на интерфейс.

person Marko Topolnik    schedule 07.07.2014
comment
Я просто добавлю, что это была одна из самых горячо обсуждаемых тем на ранней стадии JSR-335. Когда мы впервые предложили правило только для интерфейсов, это казалось рискованным. Но поскольку на это ушло несколько лет, я абсолютно убежден, что мы поступили правильно. Мы получили значительную простоту и гибкость (которые достанутся всем пользователям в виде более высокой производительности и более гибкой будущей эволюции языка) за счет отказа от нескольких крайних случаев использования. - person Brian Goetz; 07.07.2014
comment
Да, на самом деле я рассматриваю именно этот аспект как наиболее ценный в целом для проекта Lambda для Java. Это кажется правильным на глубоком уровне, даже более правильным, чем многие другие функции, которые мы видели в эволюции языка, и указывает на новые, захватывающие направления для будущего Java. - person Marko Topolnik; 08.07.2014
comment
Я не вижу, чтобы Брайан Гетц высказал здесь какие-либо МЫСЛИ. Одни бессмысленные СЛОВА. Лямбды — это синтаксический сахар для анонимных внутренних классов. Тогда зачем добавлять горькое в сахар?! - person Dims; 20.12.2016
comment
@Dims Lambdas - это не синтаксический сахар для анонимных внутренних классов, в этом весь смысл. Каковы ваши полномочия утверждать обратное? - person Marko Topolnik; 20.12.2016