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