Странная проблема дженериков

Кто-либо знает, почему следующий код не компилирует, и во время компиляции я получаю несовместимое исключение типов?

public class Test<T> {

public static void main(String[] args)
{
    // using Test<?> solves the compilation error
    Test test = new Test();

    // getting error incompatible types:
    // found   : java.lang.Object
    // required: java.lang.Integer
    Integer number = test.getDays().get(0);
}


private List<Integer> getDays() {
    return new ArrayList<Integer>();
}

}

и почему использование Теста с неограниченным подстановочным знаком решает это? Я использую версию 1.6.0_12 Java

5
задан Samuel Neff 28 June 2010 в 13:41
поделиться

6 ответов

Небольшое отличие от ответа Аделя, но вы имели в виду это?

public class Test<T> {

public static void main(String[] args)
{
    Test<Integer> test = new Test<Integer>();

    Integer number = test.getDays().get(0);
}


private List<T> getDays() {
    return new ArrayList<T>();
}

} 
3
ответ дан 18 December 2019 в 14:42
поделиться

Когда вы объявляете переменную или поле как необработанный тип, все использования этого поля или переменной теряют всю общую информацию, а не только общую информацию, относящуюся к переменной типа, отброшенной необработанным типом. Это означает, что ваш вызов test.getDays () вернул List , а не List , хотя Integer не имеет отношения к T.

0
ответ дан 18 December 2019 в 14:42
поделиться

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

Вы можете инстанцировать тест следующим образом:

Test<JFrame> test = new Test();

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

Если убрать родовое объявление, он тоже работает (конечно).

1
ответ дан 18 December 2019 в 14:42
поделиться

Я интерпретирую вопрос как почему test.getDays () не возвращает List , когда тип возврата не зависит от параметра типа, T ?

Когда вы создаете переменную, которая является необработанной ссылкой на экземпляр Test , компилятор отбрасывает все универсальные шаблоны для доступа через эту переменную ( для обратной совместимости).

Поскольку для теста не указан его тип , это также означает, что для getDays равно отброшен.

8
ответ дан 18 December 2019 в 14:42
поделиться

Компилятор не может определить фактический тип для Test, поскольку вы указали его как общий, а затем использовали необработанный тип. Добавление? подстановочный знак сообщает компилятору, что фактический класс может быть определен только во время выполнения; он не будет проверять тип класса.

Вы также можете решить проблему компиляции, сделав класс Test неуниверсальным или заставив getDays () возвращать List.

0
ответ дан 18 December 2019 в 14:42
поделиться

Попробуйте следующее:

public class Test<T> {

public static void main(String[] args)
{
    // using Test<?> solves the compilation error
    Test<Integer> test = new Test<Integer>();

    // getting error incompatible types:
    // found   : java.lang.Object
    // required: java.lang.Integer
    Integer number = test.getDays().get(0);
}


private List<Integer> getDays() {
    return new ArrayList<Integer>();
}

} 
1
ответ дан 18 December 2019 в 14:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: