Отвечая на вопрос об этом здесь: https://stackoverflow.com/a/9872630/82609
Я попытался сделать следующее:
Comparator[] comparators = new Comparator[] {...};
Работает! Но в следующем нет:
Comparator[] comparators = new Comparator[] {...};
По связанному с этим вопросу я сделал предположение:
Я думаю, это потому, что изначально контракт массива может быть чем-то примерно так:
Если вы создадите массив типа X, вы НИКОГДА НИКОГДА не сможете поместить что-нибудь в нем, что НЕ ЯВЛЯЕТСЯ X. Если вы попытаетесь, вы получите ArrayStoreException
. Таким образом, разрешение создания массивов с дженериками приведет к другому например:
Если вы создадите массив типа
X
, вы НИКОГДА НИКОГДА не сможете поставить что-нибудь, что НЕ ЯВЛЯЕТСЯ X. Если вы попробуете, вы получите ArrayStoreException. Но вы МОЖЕТЕ добавить оба объектаX
иX
из-за стирания типов!
Но, если подумать, не будет ли проблемой иметь:
Comparator[] comparators = new Comparator[] {...};
Я действительно не понимаю, почему это невозможно, поскольку использование такой вещи будет:
Наконец-то мы можем использовать массив со ссылкой на общий тип, и из-за невозможности создать массив с общим типом, я думаю, многие люди даже не знают, что это возможно.
Мне просто интересно, знает ли кто-нибудь причину этого выбора?
Это немного похоже на принуждение людей использовать List
вместо использования List
dimitrisli вы привели хороший пример из знаменитой книги Джошуа Блоха.Как вы объяснили, опасно использовать оба общих массива + ковариацию и может привести к ClassCastException, в то время как мы ожидаем ArrayStoreException от массива с использованием ковариации.
Но обратите внимание, что следующее по-прежнему допустимо и ведет к тому же:
List[] stringLists = new List[1];
List intList = Arrays.asList(42);
Object[] objects = stringLists;
objects[0] = intList;
String s = stringLists[0].get(0);
Однако во время компиляции он выдает предупреждение о непроверенном приведении и, как вы упомянули, ClassCastException во время выполнения.