Обобщения Java и инициализация массива - PullRequest
18 голосов
/ 22 января 2009

Чем объясняется следующее:

public class GenericsTest {
    //statement 1
    public ArrayList<Integer>[] lists;

    public GenericsTest()
    {
            //statement 2
        lists = new ArrayList<Integer>[4];
    }
}

Компилятор принимает оператор 1. Оператор 2 помечен компилятором как «создание универсального массива».

Хорошим объяснением, которое я видел относительно запрета универсальных массивов, является этот , утверждающий, что, поскольку массивы ковариантны, а универсальные не являются, вы могли бы подорвать универсальную типизацию, если разрешили универсальные массивы.

Оставляя в стороне аргумент о том, должен ли язык идти на крайние этапы создания такого рода сложной непоследовательности в обработке дженериков, чтобы вы не стреляли в себя независимо от того, как сильно вы пытаетесь (и если кто-то знает о каких-либо хороших дискуссиях) По поводу относительных достоинств / недостатков вопроса, пожалуйста, напишите, мне было бы интересно увидеть аргументы), почему утверждение (1) должно быть разрешено, если (2) нет?

Ответы [ 4 ]

6 голосов
/ 22 января 2009

Это потому, что вы не можете создать, но вы можете использовать их:

public class GenericsTest {
    //statement 1
    public ArrayList<Integer>[] lists;

    public GenericsTest()
    {
        //statement 2
        lists = new ArrayList[4];
        //statement 3
        lists[0].add(new Integer(0));
        //statement 4
        lists[0].add(new String(""));
    }
}

Возможно утверждение 3, утверждение 4 приведет к ошибке компилятора.

1 голос
/ 22 января 2009

Кажется, есть неясные случаи, когда вы можете непреднамеренно вызвать ClassCastException, как описано здесь http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf (раздел 7.3)

интересную дискуссию на эту тему можно найти здесь http://courses.csail.mit.edu/6.170/old-www/2006-Spring/forum/index.php%3Ftopic=324.msg1131.html

0 голосов
/ 23 января 2009

Таким образом, фактический вопрос: почему нет ошибки для объявления универсального массива?

Вы всегда получите ошибку в тот момент, когда вы делаете что-то ошибочное. Добавление ошибки, если технически проблемы нет, просто добавляет беспорядок (хотя редактор может захотеть указать вам на это).

В некоторых обстоятельствах вы можете немного изменить правила с помощью непроверенного приведения. Нет необходимости заставлять код засыпать большим количеством подавлений предупреждений, чем необходимо (кроме указания на глупость).

0 голосов
/ 22 января 2009

В этом случае я бы не использовал массивы именно по этой причине. Объявление «списков» в вашем исходном коде может быть

List<List<Integer>> lists = new ArrayList<List<Integer>>(4);
for(int i = 0; i < 4; i++) lists.add(null); // or add an empty ArrayList<Integer>

(вы должны использовать интерфейс, а не реализацию в объявлениях переменных)

Вместо синтаксиса array [] вы должны использовать get () или set (). Кроме этого, это эквивалентно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...