Где определение непроверенного предупреждения для преобразования объекта в универсальный тип? - PullRequest
0 голосов
/ 04 марта 2019

JLS 5.1.9 определяет непроверенное преобразование следующим образом:

Пусть G назовет объявление универсального типа с n параметрами типа.

Существуетнепроверенное преобразование из необработанного класса или типа интерфейса G в любой параметризованный тип формы G<T1,...,Tn>.

Существует непроверенное преобразование из необработанного типа массива G[] в любой тип типа массива формы G<T1,...,Tn>[].

Использование непроверенного преобразования вызывает предупреждение непроверенного времени компиляции, если G<...> не является параметризованным типом, в котором все аргументы типа являются неограниченными подстановочными знаками, или предупреждение непроверенного подавляется аннотацией SuppressWarnings

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

public class DoubleStar{

    public static void print(Object object){
       ((A<String>)object).print();
    }

    public static void main(String[] args){
        print(new Object());
    }
}

class A<T>{
    public void print(){
        System.out.print("HELLO");
    }
}

As Объект не является необработанным типом (AFAIK), почему вышеупомянутый код должен генерировать непроверенное предупреждение о приведении и где это поведение определяется?

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Вы смотрите не на тот раздел, поэтому, кажется, это не имеет смысла в контексте вашего примера.

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

См. 5.5.2 "Проверенные и непроверенные преобразования"

Приведение типа S к типу T статически известно как правильное тогда и только тогда, когда S <: T (§4.10). </p>

Приведениеот типа S к параметризованному типу (§4.5) T не проверяется, если не выполнено хотя бы одно из следующих условий:

  • S <: T </li>
  • Все аргументы типа (§4.5.1) T являются неограниченными подстановочными знаками
  • T <: S и S не имеет подтипа X, кроме T, где аргументы типа X не содержатся в аргументах типа T. </li>

Преобразование из типа S в переменную типа T не проверяется, если только S <: T. </p>

Непроверенное приведение от S к T не является полностью не проверенным , если приведение из |S |к | T |статически известно, что это правильно.В противном случае это частично не проверено .

Непроверенное приведение вызывает предупреждение о непроверенном времени компиляции, если оно не подавлено аннотацией SuppressWarnings (§9.6.3.5).

Aприведение проверено , если статически неизвестно, что оно правильное и оно не проверено.

Если приведение к ссылочному типу не является ошибкой во время компиляции, существует несколько случаев:

  • Статически известно, что приведение является правильным.

Никакое действие во время выполнения не выполняется для такого приведения.

  • Приведениеявляется полностью непроверенным составом.

Никакое действие во время выполнения не выполняется для такого приведения.

  • Приведение является частично непроверенным приведением.

Такое приведение требует проверки достоверности во время выполнения.Проверка выполняется так, как если бы приведение было проверено между | S |и | T |, как описано ниже.

  • Приведение является проверенным приведением.

Такое приведение требует проверки достоверности во время выполнения.Если значение во время выполнения равно нулю, тогда приведение разрешено.В противном случае, пусть R будет классом объекта, на который ссылается эталонное значение времени выполнения, и пусть T будет стиранием (§4.6) типа, указанного в операторе приведения.Преобразование приведения должно проверять во время выполнения, что класс R совместим по присваиванию с типом T, с помощью алгоритма в §5.5.3.

Обратите внимание, что R не может быть интерфейсом, когда эти правила впервые применяютсядля любого данного приведения, но R может быть интерфейсом, если правила применяются рекурсивно, поскольку ссылочное значение времени выполнения может ссылаться на массив, тип элемента которого является типом интерфейса.

0 голосов
/ 04 марта 2019

Поскольку при преобразовании Object в A<String> компилятор не может проверить (или сгенерировать код для проверки), что Object действительно A<String>, а не A<Integer> (или что угодно).

...