Here's my sample code:
public class MyList<T extends Number> {
private List<T> items;
public void func() {
items.add(Integer.valueOf(1));
}
}
I think I should be able to add integer to items, but compilation fails:
Required type: T
Provided: Integer
Anyone knows what's wrong here?
Let us consider a more complete version of your example:
Suppose for the sake of argument that the compiler says that is OK.
And now we will create an instance and call the
func
method:Here is what happens.
We create a
MyList
instance whereT
isDouble
. That's OK: theDouble
class implements theNumber
interface.The
items
has a notional type ofList<Double>
and we initialize it with anArrayList
. So we now have a list what should only containDouble
values.In the call to
func
we attempt to add anInteger
to theList<Double>
. That is wrong!That is what the compilation error is saying with the
Required type: T Provided: Integer
message.To spell it out, the compiler expects a value whose type is the type that
T
is going to be at runtime. But you have given itInteger
. WhileInteger
implements theNumber
interface, it is not necessary the same as whatT
will be at runtime. That is the root cause of your compilation error.So what is the solution?
Well it depends on what the (actual) problem that this example is intended to solve. If you want
item
to be able to hold anyNumber
, you should changeto
and
items.add(Integer.valueOf(1))
should work.On the other hand, if you want to add
1
toitems
as an instance of the runtime type ofT
, that is much more difficult. The problem is that the code ofMyList
(as written) does not and cannot know what that type is! So, you need to EITHER pass theT
instance representing1
as a parameter tofunc
OR pass aClass<T>
parameter tofunc
or the constructor and use reflection to create the instance of that class to represent1
.But if you want something to auto-magically convert the
Integer
to what ever the actual runtime type ofT
is ... that is not possible.