The generic return type of the implicit generic type declared with a template
Imagine this piece of code:
public static <T> T[] superClassArray(Class<? extends T[]> subClass) {
T[] superArray = (T[]) Array.newInstance(subClass.getComponentType().getSuperclass(), 0);
return superArray;
}
The return type of T[]
this method would be any type given as an argument subClass
, even thought is subClass
not guaranteed to actually represent T[]
, but just a subclass ( ? extends T
). So the actual return type must be Object
, since it is T[]
not more explicitly declared than any superclass from subClass
.
Nevertheless,
Integer[] objA = superClassArray(Integer[].class);
compiles because it mistakenly expects to return an object Integer[]
, but explicitly throws it away ClassCastException
because the object is Number[]
indeed returned.
So, is there an excuse for mistreating generic types only declared through rather vague wildcards, or am I wrong at any point in my consideration?
source to share
As I understand it, you are not very consistent in what you are trying to do. With your method, you create a SUPERTYPE array of your class that actually gets executed.
But then you are trying to assign it to a SUBTYPE reference, which is illegal. If you are really sure that this array cannot contain values of any other type than Integer, you can use it explicitly:
Integer[] objA = (Integer[]) superClassArray(Integer[].class);
BUT I don't see any value whatsoever in code like this and in the real world, if you have a problem you are trying to solve with something like this, you really think about it a few more times and come up with a better solution. :)
source to share
You don't have to do manual casting. Generics should handle this at compile time. If you get a compile-time error, it is better to fix it instead of doing unsafe casting in your below code snippet.
T[] superArray = (T[])Array.newInstance(subClass.getComponentType().getSuperclass(), 0);
source to share