Explaining the issue with an example:
public class DataWrapper<T> {
T data;
};
DataWrapper<Object> obj1 = new DataWrapper<Object>();
List<DataWrapper<?>> anyDataList = Arrays.asList(obj1); //this doesn't work
DataWrapper<Integer> objInt = new DataWrapper<Integer>();
anyDataList = Arrays.asList(obj1, objInt); //this work
I couldn't understand why "Arrays.asList(obj1)" doesn't work?
Java 7 was stupid (not it wasn't) when inferring type arguments for generic methods. For example, it would use the declared type of an argument to infer the type regardless of the context of the method invocation. So in
Arrays.asList(obj1);
the type argument would be inferred as
DataWrapper<Object>
the method's return type would then be List<DataWrapper<Object>>
which is no assignable to a List<DataWrapper<?>>
.
In
Arrays.asList(obj1, objInt);
the type is inferred from both arguments. A common type is found between the two. In this case, that's ? extends Object
. The method return type becomes List<DataWrapper<? extends Object>>
which is assignable to List<DataWrapper<?>>
.
In Java 8, what you posted works out of the box. In Java 7, you can provide an explicit type argument to make it work
List<DataWrapper<?>> anyDataList = Arrays.<DataWrapper<?>>asList(obj1);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With