Invoking Java Generic Methods

Yann-Gaël Guéhéneuc picture Yann-Gaël Guéhéneuc · Apr 8, 2013 · Viewed 34.3k times · Source

I am studying Java generic feature and I am not sure how to explain the third line in the following main method:

public class Example4 {
    public static void main(final String[] args) {
        System.out.println(Util.<String>compare("a", "b"));
        System.out.println(Util.<String>compare(new String(""), new Long(1)));
        System.out.println(Util.compare(new String(""), new Long(1)));
    }
}

class Util {
    public static <T> boolean compare(T t1, T t2) {
        return t1.equals(t2);
    }
}

The first line compiles, runs, and returns (as expected) false.

The second line does not compile as expected, because I am explicitely mixing String and Long.

The third line compiles, runs, and return false but I am not sure to understand how it happens to work: does the compiler/JVM instantiates the parameter type T as Object? (Also, would there be a way to obtain this declared type of T are runtime?)

Thank you.

Answer

user1131435 picture user1131435 · Apr 8, 2013

The shared inherited type of String and Long is Object.

When you run this function as Util.<String>compare( the compiler expects to find two string inputs, and gives an error when it doesn't. However, running it without <String> results in the use of the closest shared inherited type - in this case, Object.

Thus, when compare accepts t1 and t2, they have been cast as Object, and the code runs fine.

To get the actual type at runtime you use the same technique that you would use with any other object: The getClass() which is inherited from the Object class.