How type inference work for method calls?

Devashish Jaiswal :

Consider the following example:

public class Learn {
    public static <T> T test (T a, T b) {
        System.out.println(a.getClass().getSimpleName());
        System.out.println(b.getClass().getSimpleName());
        b = a;
        return a;
    }

    public static void main (String[] args) {
        test("", new ArrayList<Integer>());
    }
}

In the main method, I am calling test with a String and an ArrayList <Integer> object. Both are different things and assigning an ArrayList to String (generally) gives a compile error.

String aString = new ArrayList <Integer> (); // won't compile

But I am doing exactly that in the 3rd line of test and the program compiles and runs fine. First I thought that the type parameter T is replaced by a type that's compatible with both String and ArrayList (like Serializable). But the two println statements inside test print "String" and "ArrayList" as types of a and b respectively. My question is, if ais String and b is ArrayList at runtime, how can we assign a to b.

rgettman :

For a generic method, the Java compiler will infer the most specific common type for both parameters a and b.

The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.

You aren't assigning the result of the call to test to anything, so there is no target to influence the inference.

In this case, even String and ArrayList<Integer> have a common supertype, Serializable, so T is inferred as Serializable, and you can always assign one variable of the same type to another. For other examples, you may even find Object as the common supertype.

But just because you have variables of type T that are inferred as Serializable, the objects themselves are still a String and an ArrayList, so getting their classes and printing their names still prints String and ArrayList. You're not printing the type of the variables; you're printing the type of the objects.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=439595&siteId=1