Непроверенное предупреждение о приведении при добавлении универсального параметра - PullRequest
0 голосов
/ 14 января 2019

Следующий код Java НЕ генерирует непроверенное предупреждение о приведении (тестирование с помощью компилятора Eclipse для Java 8):

class Parent<T> {}

class Child<T> extends Parent<T> {}

class Test {
    <T> void test() {
        Parent<T> p = new Child<T>();
        // cast accepted by compiler:
        Child<T> cast = (Child<T>)p;
    }
}

Итак, я понимаю, что компилятор, должно быть, каким-то образом обнаружил, что если p является и Parent<T> (по типу времени компиляции), и Child (по типу исполнения во время выполнения), то можно предположить, что это Child<T>, поскольку Child передает свой параметр типа в предложении extends.

Однако следующий подобный код генерирует непроверенное предупреждение о приведении:

class Parent<T> {}

class Child<T, U> extends Parent<T> {}

class Test {
    <T, U> void test() {
        Parent<T> p = new Child<T, U>();
        // cast considered unsafe by compiler:
        Child<T, ?> cast = (Child<T, ?>)p;
    }
}

Тем не менее, рассуждения о первом безопасном примере также должны применяться здесь! Если p является Parent<T> и Child, то это должно быть Child<T, ?>, учитывая Child 'extends предложение!

(Обратите внимание, что я НЕ включаю U в приведение, потому что это действительно не может быть проверено ни во время компиляции, ни во время выполнения.)

Есть ли способ привести к подтипу, имеющему дополнительные параметры, без предупреждений?

1 Ответ

0 голосов
/ 15 января 2019

Как сказано в моем комментарии, эти два приведения работают в компиляторе Oracle Java 1.8.0_112, так что, по-видимому, это ошибка или ограничение компилятора, если хотите.

Я полагаю, что оба приведения НЕ должны быть небезопасными, следуя принципу, согласно которому класс Subclassing является правильным (т. Е. Экземпляр действительно Child). Должно быть верно, что он совместим с Child<T, ?>, если это Parent<T>. Напротив, это не сработает (т.е. выдаст предупреждение), если вы попытаетесь привести его к чему-то вроде Child<U, V>, где U не гарантированно будет T или V - это не что иное, как ?, потому что есть Дети, которые Parent<T> не обязательно Child<U, V>.

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