Предупреждение о непроверенном назначении, когда в содержащем классе отсутствует общий тип

Я получаю «Непроверенное назначение: java.util.List to java.util.List<java.lang.Integer>» в строке с комментарием. Предупреждение сбрасывается при изменении параметра GetList на GetList<?>.

Я не понимаю, почему общий тип GetList может повлиять на результат getIntegerList(). Пробовал как в Intellij Idea, так и в Eclipse. Это нормально или предупреждающее сообщение неверно?

import java.util.ArrayList;
import java.util.List;

public class GetList<T> {
    private final List<Integer> integerList= new ArrayList<Integer>();

    public List<Integer> getIntegerList() {
        return integerList;
    }
}


import java.util.List;

public class Main {
    public Main(GetList getList) {
        List<Integer> rahan = getList.getIntegerList(); //this line shows the warning above
    }
}

person Vlad Topala    schedule 15.03.2016    source источник
comment
Использование необработанных типов всегда вызывает это предупреждение. Кстати, вам действительно нужен параметр <T> в вашем классе GetList?   -  person Francesco Pitzalis    schedule 15.03.2016
comment
Это не имеет ничего общего с Java. Я попробовал ваш код в Intellij, и он не показал никаких предупреждений. Должно быть, ваша IDE неправильно интерпретирует   -  person Radu Ionescu    schedule 15.03.2016
comment
@RaduIonescu или, может быть, это ваша IDE, потому что я могу воспроизвести, используя javac -Xlint:warning.   -  person Andy Turner    schedule 15.03.2016
comment
@FrancescoPitzalis это просто SSCCE для понимания проблемы. Код, в котором я нашел это, использует generic.   -  person Vlad Topala    schedule 15.03.2016
comment
Я не могу найти очевидную причину этого предупреждения в JLS; однако, как сказано в Раздел 4.8 Использование необработанных типов в коде, написанном после введения обобщений в язык программирования Java, настоятельно не рекомендуется; так что это счастливое (?) совпадение, что исправление одного предупреждения (видимого через -Xlint:rawtypes) также исправляет имеющееся под рукой.   -  person Andy Turner    schedule 15.03.2016
comment
@AndyTurner соответствующий абзац: Тип конструктора (§8.8), метода экземпляра (§8.4, §9.4) или нестатического поля (§8.3) необработанного типа C, который не унаследован от его суперклассов или суперинтерфейсов. необработанный тип, который соответствует стиранию его типа в общем объявлении, соответствующем C. Таким образом, GetList<T>.getIntegerList() возвращает List<Integer>, а GetList.getIntegerList() возвращает List.   -  person Roman    schedule 15.03.2016
comment
@Роман ты уверен? Я видел это и на самом деле попытался определить метод в несыром базовом классе и все равно получил предупреждение (позвольте мне попробовать еще раз...)   -  person Andy Turner    schedule 15.03.2016
comment
@Roman, конечно, ты прав - я определял метод в базовом классе, но затем снова переопределял его в классе GetList. Спасибо, что указали на это!   -  person Andy Turner    schedule 15.03.2016
comment
@AndyTurner имейте в виду, что если базовый класс также является универсальным, применяется предыдущий абзац: суперклассы (соответственно, суперинтерфейсы) необработанного типа являются стиранием суперклассов (суперинтерфейсов) любой из параметризаций универсального типа.   -  person Roman    schedule 15.03.2016
comment
Возможный дубликат универсальных методов Java в универсальных классах   -  person dimo414    schedule 19.04.2016
comment
См.: stackoverflow.com/help/someone-answers.   -  person c0der    schedule 23.04.2018


Ответы (1)


Если вы используете необработанные типы, вы должны ожидать любое количество странных предупреждений, и эти предупреждения не обязательно будут согласовываться между компиляторами (вы входите на территорию «неопределенного поведения»).

Как отмечают Энди Тернер и Роман в комментариях, это указано в JLS §4.8 (выделено мной):

Тип конструктора (§8.8), метода экземпляра (§8.4, §9.4) или нестатического поля (§8.3) необработанного типа C, который не унаследован от его суперклассов или суперинтерфейсов. это необработанный тип, который соответствует удалению его типа в универсальном объявлении, соответствующем C.

Другими словами, компилятору разрешено отбрасывать всю общую информацию о классе, когда он используется как необработанный тип.

Вот еще один пример (с немного более четким сообщением об ошибке):

$ cat Demo.java
import java.util.*;

class Demo<T> {
  public List<Integer> ls() { return new ArrayList<>(); }

  public static void main(String[] args) {
    List<Integer> ls = new Demo().ls();
  }
}

$ javac -Xlint:unchecked Demo.java 
Demo.java:7: warning: [unchecked] unchecked conversion
    List<Integer> ls = new Demo().ls();
                                    ^
  required: List<Integer>
  found:    List
1 warning
person dimo414    schedule 19.04.2016