На тип возвращаемого метода влияет параметр типа класса, хотя параметр типа нигде не используется. Почему?

Почему в следующем исходном коде на возвращаемый тип метода 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();
    }
}

Что вы подразумеваете под «зависит от параметра типа»? У вас есть исключение?

QBrute 02.04.2024 19:38

Да, у меня есть исключение. (Я просто изменил код, чтобы сделать это очевидным.)

Marián Petráš 02.04.2024 19:47

@MariánPetráš Возможно, вы захотите посмотреть stackoverflow.com/questions/2770321/…

Progman 02.04.2024 20:05
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Так почему же final Long val3 = new WParam<>().unwrap(new Wrapper<>(5L)) работает, а final Long val2 = new WParam().unwrap(new Wrapper<>(5L)); нет?

Это сводится к тому, что new WParam() является необработанным типом и поэтому теряет всю информацию о типе. Все универсальные типы, не используемые в статическом контексте, удаляются, даже те, которые не принадлежат параметру типа в определении вашего класса.

Вот почему возвращаемый тип unwrap на самом деле равен Object и не может быть приведен к Long, как и говорит исключение.

Для получения дополнительной информации посмотрите Что такое необработанный тип и почему нам не следует его использовать?

«Все универсальные типы, не используемые в статическом контексте, удаляются, даже те, которые не принадлежат параметру типа в определении вашего класса». – Это ключевая часть. Спасибо.

Marián Petráš 02.04.2024 21:04

Другие вопросы по теме