Почему я получаю сообщение об ошибке, устанавливая параметр типа Integer в переменную Integer в общих? - PullRequest
1 голос
/ 16 мая 2019

У меня есть следующая программа:

class MyGenClass{

    public <T> void setAge(T ageParam){
        Integer age = ageParam;
    }

}
class Program{

    public static void main(String args[]){

        MyGenClass gnClass = new MyGenClass();
        gnClass.<Integer>setAge(80);

    }

}

На самом деле, я передаю Integer, тогда почему ageParam не присваивается age. И когда я делаю:

class MyGenClass{

    public <T> void setAge(T ageParam){
        T age = ageParam;
    }

}

Почему переменная универсального типа не назначена переменной типа Integer age На самом деле переменная универсального типа ageParam имеет значение Integer. Обязательно ли ageParam присваивать переменной типа T? Какой сценарий стоит за этим?

Ответы [ 2 ]

3 голосов
/ 16 мая 2019

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

public <T extends Integer> void setAge(T ageParam){
    age = ageParam;
}

Однако я не вижу в этом смысла.Рассмотрим следующий подход ради изменчивости:

class MyGenClass {
    Number age;
    public <T extends Number> void setAge(T ageParam){
        age = ageParam;
    }
}

Поэтому возможно следующее (аргументы явного типа могут быть выведены, подумано):

MyGenClass gnClass = new MyGenClass();
gnClass.<Integer>setAge(80);
gnClass.<Long>setAge(80L);
gnClass.<Double>setAge(80.0);
gnClass.<Float>setAge(80.0F);
2 голосов
/ 16 мая 2019

Посмотрите на свои MyGenClass в изоляции. T может быть буквально чем угодно. Это не обязательно целое число. Я мог бы назвать это с помощью String, или HashMap, или ArrayList, или буквально что-нибудь еще .

MyGenClass gnClass = new MyGenClass();
gnClass.setAge("hello");
gnClass.setAge(new HashMap<String, String>());
gnClass.setAge(new ArrayList<String>());

Во всех этих случаях присваивание переменной Integer недопустимо, следовательно, ошибка компилятора.

Вы только случайно вызываете его с целым числом в вашем примере. Компилятор не может утверждать, что так будет всегда.

Похоже, вы вообще не должны использовать дженерики. Просто измените подпись на

public void setAge(Integer ageParam)
...