In this program I am creating a generic method in which second parameter extends first parameter but when I am passing String as first paameter and Integer array as second parameter then too the program is running fine. Why is it not giving compile time error as Integer does not extends String?
class GenericMethodDemo {
static <T, V extends T> boolean isIn(T x, V[] y) {
for (int i = 0; i < y.length; i++) {
if (x.equals(y[i])) {
return true;
}
}
return false;
}
public static void main(String args[]) {
Integer nums[] = {1, 2, 3, 4, 5};
if (!isIn("2", nums)) {
System.out.println("2 is not in nums");
}
}
}
This compiles without error as the type system will infer the nearest common supertype between the two type arguments.
In the supplied example the nearest common supertype is
Object
.If we supply a double as the first parameter
Number
will be the inferred type as it is the nearest common supertype betweenDouble
andInteger
.As azurefrog stated, to prevent compilation type witnesses (
GenericMethodDemo.<String, Integer>isIn("2", nums)
) would be required to prevent type inference from using the nearest common supertype.The Java Language Specification details regarding type inference can be found here: https://docs.oracle.com/javase/specs/jls/se8/html/jls-18.html