I have below generic method that returns a generic array:
public static T[] genericMethod1(List input) {
T[] res = (T[]) new Object[input.s
The explanation for what you are seeing is due to something called type erasure. Here is what your genericMethod()
will look like after the compiler performs type erasure:
public static Object[] genericMethod(List input) {
Object[] res = new Object[input.size()];
int i = 0;
for (Object t : input) {
res[i] = t;
i++;
}
return res;
}
In other words, this method will return an array of type Object
. There is no way to cast an Object[]
to an Integer[]
because they are not the same type. If you want your method to be able to dynamically return the type you want, then you can use Array.newInstance()
. This will require also passing in the type of the array you want as an input parameter:
public static T[] genericMethod(Class clazz, List input) {
@SuppressWarnings("unchecked")
T[] res = (T[]) Array.newInstance(clazz, input.size());
int i = 0;
for (T t : input) {
res[i] = t;
i++;
}
return res;
}
Now your code snippet will run without error:
LinkedList list = new LinkedList();
Integer[] i = genericMethod(Integer.class, list);
Update:
Your second method, genericMethod2()
, will look like this after type erasure:
public static Object genericMethod2(List input) {
return input.get(0);
}
It will return the first element of the input list, cast to Object
. Here is your usage of that method:
Integer j = genericMethod2(list);
The compiler will try to cast the output from genericMethod2()
to Integer
:
Integer j = (Integer)genericMethod2(list);
This cast is legal, because every Integer
is also an Object
, and furthermore it succeeds here because you passed in a collection of Integer
. This second method is not the same scenario as the first one you highlighted for us.