Страницы

Поиск по вопросам

воскресенье, 22 декабря 2019 г.

Почему тип дженрика нужно указывать второй раз при использовании {{}}?

#java


Почему так можно:

ArrayList list = new ArrayList();


А так нельзя: 

ArrayList list = new ArrayList(){{
   add(0);
}};


Почему так сделали?
    


Ответы

Ответ 1



Используя так называемый double-brace initialization, вы создаёте новый анонимный класс. Когда в Java-7 разрешили опускать аргументы типа в некоторых случаях, одним из исключений, явно прописанным в стандарте, являются как раз анонимные классы: It is a compile-time error if a class instance creation expression declares an anonymous class using the "<>" form for the class's type arguments. Тут нет каких-то принципиальных ограничений, просто усложняло вывод типов в компиляторе, потому что есть много частных случаев. Поэтому недоделали. В Java-9 планируют исправить этот момент — смотрите баг JDK-8073593. В заключение скажу, что double-brace initialization — исключительно дурацкий способ инициализации объектов. У него могут быть неожиданные проблемы: от случайного захвата контекста внешнего класса до смены serialVersionID. В вашем случае это вообще не нужно. Пишите так: List list = new ArrayList<>(Arrays.asList(0)); А если не собираетесь в будущем добавлять и удалять элементы в список, то лучше так: List list = Arrays.asList(0); Но даже если б у вас была Map, лучше заведите отдельный метод, фабрику или билдер, который создаёт предопределённые Map, но не делайте double-brace initialization. В той же девятке, кстати, планируется упростить этот момент — смотрите JDK-8048330. Будет можно писать List list = List.of(1,2,3,4); Set set = Set.of("aa", "bb", "cc"); Map map = Map.of("aa", 1, "bb", 2, "cc", 3);

Комментариев нет:

Отправить комментарий