Инициализация с двойной скобкой (анонимный внутренний класс) с оператором diamond - PullRequest
11 голосов
/ 19 марта 2012

Мне интересно, почему второе объявление карты (с использованием оператора diamond) не компилируется, когда первое делает.Ошибка компиляции:

ошибка: невозможно определить аргументы типа для HashMap;Карта map2 = new HashMap <> () {причина: нельзя использовать '<>' с анонимными внутренними классами, где K, V являются переменными типа: K расширяет объект, объявленный в классе HashMap V расширяет объект, объявленный в классе HashMap

Код:

    Map<String, String> map1 = new HashMap<String, String>() { //compiles fine

        {
            put("abc", "abc");
        }
    };

    Map<String, String> map2 = new HashMap<>() { //does not compile

        {
            put("abc", "abc");
        }
    };

РЕДАКТИРОВАТЬ
Спасибо за ваши ответы - я должен был лучше прочитать ошибку компиляции.Я нашел объяснение в JLS

Это ошибка времени компиляции, если выражение создания экземпляра класса объявляет анонимный класс, используя форму "<>" для типа классааргументы.

Ответы [ 4 ]

6 голосов
/ 19 марта 2012

Здесь у вас нет статического инициализатора (ключевое слово static отсутствует вообще).

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

Поскольку вы получите анонимный подкласс HashMap, оператор diamond здесь не работает, поскольку подкласс будет скомпилирован, как если бы вы написали ... extends HashMap<Object, Object>, и это явно не совместимо с Map<String, String>.

4 голосов
/ 19 марта 2012

Алмазный вывод не работает для создания экземпляров анонимных классов, что вы и делаете здесь.

Попробуйте это:

Map<String, String> map1 = new HashMap<>();

{
    map1.put("abc", "abc");
}
3 голосов
/ 10 мая 2015

Эта функция является частью Project Coin 2 и будет доступна в Java 9 с 22 сентября 2016 года.

Это вызов Allowing the diamond syntax with some anonymous class constructors.

Link.

1 голос
/ 12 июня 2014

Обратите внимание, что вы могли бы также вообще опустить бриллиант. Тем не менее, хотя он компилируется, он только потому, что игнорирует обобщения Java и опирается на тот факт, что Java обратно совместима с предыдущими версиями.

Map<String, String> map1 = new HashMap() { //compiles fine
    {
        put("abc", "abc");
    }
};
...