Ankit Srivastava
Ankit Srivastava

Reputation: 29

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

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

Upvotes: 1

Views: 329

Answers (1)

Jeff
Jeff

Reputation: 3882

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

Upvotes: 2

Related Questions