Shadab Faiz Shadab Faiz - 2 months ago 15
Java Question

Type conversion error in Generic

I have just started learning about Generic.Here i'm trying to set value of global obj to the local obj's value.But i'm getting type conversion error.What is the cause for this error?

class GenUpperBound<T>
{
T obj;
public <T extends Number> void set(T obj)
{
this.obj=obj;
}

public static void main(String...q)
{
GenUpperBound<Integer> w=new GenUpperBound<>();
w.set(10);
}
}


Here is the error....

GenupperBound.java:6: error: incompatible types: T#1 cannot be converted to T#2
this.obj=obj;
^
where T#1,T#2 are type-variables:
T#1 extends Number declared in method <T#1>set(T#1)
T#2 extends Object declared in class GenUpperBound
1 error

Answer

The constructor-scoped type-parameter <T extends Number> hides the class-scoped type-parameter <T>. Those two T's do not represent the same type.

This is why the compiler rejects to compile your code, because the argument in the constructor could be potentially of a different type than the type, by which the class is parameterized. For example:

new GenUpperBound<String>(new Integer(1));

The difference can be clearly seen if you change the constructor-scoped type-parameters' name to U:

class GenUpperBound<T> {

   T obj;

   public <U extends Number> void set(U obj) {
      this.obj=obj;
   }

   ...
}

Now this compiles fine, too, but T and U clearly represent different types.


You could fix this problem with:

class GenUpperBound<T extends Number> {

   T obj;

   public void set(T obj) {
      this.obj=obj;
   }
...
}

Now there isn't a second T type-parameter, but the constructor uses the class-scoped one. In this case statements like new GenUpperBound<String>(new Integer(1)); will not compile, because the argument is not of the same type as the one that the instance is parameterized with.

Comments