Shadab Faiz
Shadab Faiz

Reputation: 2508

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

Upvotes: 0

Views: 177

Answers (3)

Konstantin Yovkov
Konstantin Yovkov

Reputation: 62864

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.

Upvotes: 4

Bene
Bene

Reputation: 734

Try this:

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

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

Upvotes: 1

torkleyy
torkleyy

Reputation: 1217

You have to declare your class like

class GenUpperBound<T extends Number>

because otherwise your obj could for example be of type String and you can't assign a Number to a String.

Upvotes: 0

Related Questions