Why is this generic method not giving compile-time error?

339 views Asked by At

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");
        }
    }
}
1

There are 1 answers

0
Jeff On

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 between Double and Integer.

public static void main(String args[]) {

    Integer nums[] = {1, 2, 3, 4, 5};

    //In this case the nearest common type is object
    if (!isIn("2", nums)) {
        System.out.println("2 is not in nums");
    }

    //In this case the nearest common type would be Number
    if (!isIn(2d, nums)) {
        System.out.println("2 is not in nums");
    }        
}

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