Given the generic method:
<T> List<T> getGenericList(int i) {...}
the following code compiles without any warning:
public List<String> getStringList(boolean b){
if(b)
return getGenericList(0);
else
return getGenericList(1);
}
but this one generates 'Type mismatch' compilation error:
public List<String> getStringList(boolean b) {
return (b) ? getGenericList(0) : getGenericList(1);
}
Why?
This is NOT a generics problem, but a consequence of the way the compiler has to infer the type of the ternary expression.
It happens the same with this equivalent code. This code works:
public byte function(boolean b){
if(b)
return 1;
else
return 2;
}
While this doesn't:
public byte function(boolean b) {
return (b) ? 1 : 2;
}
The reason is that when the compiler tries infer the type of this expression
return (b) ? 1 : 2;
It first has to obtain the type of each one of the operands, and check if they are compatible (reference) to evaluate wether the ternary expression is valid or not. If the type of the "return" were propagated to automatically cast or promote each one of the operands, it could lead to resolve the type of a ternary expression differently depending on the context of this expression.
Given that the type of the "return" cannot be propagated to the operands, then in the menctioned case:
return (b) ? getGenericList(0) : getGenericList(1);
the binding of the generic type cannot be done, so the type of each one of the operands is resolved to List<Object>
. Then the compiler concludes that the type of the whole expression is List<Object>
, which cannot be automatically casted to List<Integer>
(because they are not compatible types).
Whereas this other one
return getGenericList(0);
It applyes the type of the "return" to bind the generic type T, so the compiler concludes that the expression has a List<String>
type, that can be returned safely.
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