Кто-либо знает, почему следующий код не компилирует, и во время компиляции я получаю несовместимое исключение типов?
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
Небольшое отличие от ответа Аделя, но вы имели в виду это?
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>();
}
}
Когда вы объявляете переменную или поле как необработанный тип, все использования этого поля или переменной теряют всю общую информацию, а не только общую информацию, относящуюся к переменной типа, отброшенной необработанным типом. Это означает, что ваш вызов test.getDays ()
вернул List
, а не List
, хотя Integer не имеет отношения к T.
Я попытался скомпилировать его, и у меня возникли те же проблемы. Я не думаю, что ОП хочет получить объяснение, как использовать дженерики. Попробуйте сами... странно то, что это "должно" работать, потому что общий тип T не используется вообще, поскольку в объявлении getDate указано, что он возвращает ссылку на список целых чисел.
Вы можете инстанцировать тест следующим образом:
Test<JFrame> test = new Test();
... и он компилируется! (конечно, вы можете использовать любой существующий тип здесь ...) Странная вещь ...
Если убрать родовое объявление, он тоже работает (конечно).
Я интерпретирую вопрос как почему test.getDays ()
не возвращает List
, когда тип возврата не зависит от параметра типа, T
?
Когда вы создаете переменную, которая является необработанной ссылкой на экземпляр Test
, компилятор отбрасывает все универсальные шаблоны для доступа через эту переменную ( для обратной совместимости).
Поскольку для теста
не указан его тип
, это также означает, что
для getDays
равно отброшен.
Компилятор не может определить фактический тип для Test, поскольку вы указали его как общий, а затем использовали необработанный тип. Добавление? подстановочный знак сообщает компилятору, что фактический класс может быть определен только во время выполнения; он не будет проверять тип класса.
Вы также можете решить проблему компиляции, сделав класс Test неуниверсальным или заставив getDays () возвращать List.
Попробуйте следующее:
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>();
}
}