Java redundant casts required in generic method
First off, this statement is logically wrong
if(type.isInstance(String.class))
If type
is Class<String>
then isInstance
is checking to see if the argument is a string instance. The argument you are passing is a class instance (specifically, a Class<String>
).
If you prefer,
String.class.isInstance(String.class) == false
What you meant was
if(type == String.class)
However, even with this logical error resolved, your code will still have an unchecked cast warning.
The part you are missing is right here
Cast to
ArrayList<T>
is required even though we know that if type String is passed as a parameter it will returnArrayList<String>
just likeforString()
method
Exactly. We know it. But what we know and what the compiler knows are two different things. The compiler is not clever enough to check the conditional and realise that the type is okay. It conceivably could be smart enough, but it is not.
This is precisely why this manifests as a warning and not as an error. It is a warning because what you are doing is potentially wrong; it is not definitely wrong, else it would not compile at all. In this case, the warning should act as a prompt for you to double-check that what you're doing is correct and then you can happily suppress it.
@SuppressWarnings("unchecked")
public static <T> ArrayList<T> function(Class<T> type){
if(type == String.class)
return (ArrayList<T>) forString();
return forGeneric(type);
}
Finally -- and it may be an artifact of your contrived example -- but all of these methods are useless. There does not seem to be any advantage over calling new ArrayList<>()
directly. At runtime, the actual instances are identical regardless of which of the 3 methods it came from.