Почему в следующем исходном коде на возвращаемый тип метода WParam.unwrap(…)
влияет параметр типа <X>
, хотя он нигде не используется?
public class TestClass {
void test() {
final Long val1 = new Simple().unwrap(new Wrapper<>(5L)); // OK
final Long val2 = new WParam().unwrap(new Wrapper<>(5L)); // ERROR: Object cannot be converted to Long
final Long val3 = new WParam<>().unwrap(new Wrapper<>(5L)); // OK
final Long val4 = new WParam<Byte>().unwrap(new Wrapper<>(5L)); // OK
}
}
record Wrapper<O>(O obj) {}
class Simple {
public <T> T unwrap(Wrapper<T> wrapper) {
return wrapper.obj();
}
}
class WParam<X> {
public <T> T unwrap(Wrapper<T> wrapper) {
return wrapper.obj();
}
}
Да, у меня есть исключение. (Я просто изменил код, чтобы сделать это очевидным.)
@MariánPetráš Возможно, вы захотите посмотреть stackoverflow.com/questions/2770321/…
Так почему же final Long val3 = new WParam<>().unwrap(new Wrapper<>(5L))
работает, а final Long val2 = new WParam().unwrap(new Wrapper<>(5L));
нет?
Это сводится к тому, что new WParam()
является необработанным типом и поэтому теряет всю информацию о типе. Все универсальные типы, не используемые в статическом контексте, удаляются, даже те, которые не принадлежат параметру типа в определении вашего класса.
Вот почему возвращаемый тип unwrap
на самом деле равен Object
и не может быть приведен к Long
, как и говорит исключение.
Для получения дополнительной информации посмотрите Что такое необработанный тип и почему нам не следует его использовать?
«Все универсальные типы, не используемые в статическом контексте, удаляются, даже те, которые не принадлежат параметру типа в определении вашего класса». – Это ключевая часть. Спасибо.
Что вы подразумеваете под «зависит от параметра типа»? У вас есть исключение?