1

I have the following program:

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);

    }

}

In fact, i am passing the Integer then why the ageParam is not assigned to age. And when i do:

class MyGenClass{

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

}

Why the generic type variable is not assigned to the Integer type variable age in fact the generic type variable ageParam is Integer. Is this compulsory that the ageParam must be assigned to the variable that is of type T? Whats the scenario behind this?

Stack Overflow
  • 1
  • 5
  • 23
  • 51
  • 1
    I guess you made up an example for this question, but just in case, generics don't make sense here. You could use `T extends Integer` to make javac happy, but `T` can't be anything else than `Integer` as `Integer` is `final`. Just make `setAge` take an `Integer`. – sp00m May 16 '19 at 08:51

2 Answers2

3

There is not assured that the type T will be compatible with Integer. To make it clear, you have to use the following approach where T would be a subtype of Integer:

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

However, I see no point on this. Consider the following approach for the sake of variability:

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

Therefore the following is possible (the explicit type arguments can be inferred, thought):

MyGenClass gnClass = new MyGenClass();
gnClass.<Integer>setAge(80);
gnClass.<Long>setAge(80L);
gnClass.<Double>setAge(80.0);
gnClass.<Float>setAge(80.0F);
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • So, you mean this error is just because of the assurity? I don't think so, may be there is something else that needs to be explained. – Stack Overflow May 16 '19 at 08:53
  • 4
    Integer is declared as final so generics here are pointless. The parameter should just be `Integer ageParam` – Michael May 16 '19 at 08:53
  • @SunnyKhan: Yes, just because of that. – Nikolas Charalambidis May 16 '19 at 08:54
  • @Michael: I am aware of that since `Integer` cannot be extended, right? For this reason, I recommend using `Number` or better use a classical setter such as ` public int void setAge(int ageParam)` – Nikolas Charalambidis May 16 '19 at 08:56
  • @Nikolas: But i think its not a solid reason, but on other hand it makes sense thats why the upper bound logic is there is generics. – Stack Overflow May 16 '19 at 08:57
  • 1
    @Nikolas Right. `Number` would only make sense if you wanted to accept floating point values as well, which for an age I'm not sure you would want to. In such a case, declaring the function as `double ageParam` would accomplish effectively the same thing anyway - no generics required. – Michael May 16 '19 at 09:00
2

Look at your MyGenClass in isolation. T could be literally anything. It is not necessarily an Integer. I could call it with a String, or a HashMap or an ArrayList, or literally anything else.

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

In all of these cases, assignment to an Integer variable is invalid, hence the compiler error.

You only happen to be calling it with an Integer in your example. The compiler cannot assert that it will always be this way.

It looks as if you should not be using generics at all. Just change the signature to

public void setAge(Integer ageParam)
Michael
  • 41,989
  • 11
  • 82
  • 128