Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is generics bound part of method signature in Java?

I realized today that this compiles and runs fine:

public class Test {
    public static <T> T handle(T val) {
        System.out.println("T");
        return val;
    }

    public static <T extends String> T handle(T val) {
        System.out.println("T extends String");
        return val;
    }
}

The two handle methods has the same name, and same number and type (?) of parameters. The only difference is that the second handle method has a stricter generic bound. IDE does not complain at all, and the code compiles fine. At run time method is selected as expected - e.g. Test.handle("this is a string") will call into the second method and Test.handle(10) will invoke the first one.

Is generics bound considered part of the method signature? or is it a method overload resolution magic?

like image 996
Xinchao Avatar asked Jul 20 '18 18:07

Xinchao


2 Answers

Generics offer compile-time type-safety; At runtime, your methods erase to the following:

public static Object handle(Object val) {
    System.out.println("T");
    return val;
}

public static String handle(String val) {
    System.out.println("T extends String");
    return val;
}

Due to method overloading, handle(String) will be called when passing a String, and handle(Object) will be called when passing any other Object (keep in mind String is final and can have no children).

like image 126
Jacob G. Avatar answered Oct 17 '22 23:10

Jacob G.


The bound of the generics is considered.

In the first case, the bound is Object; in the second case, the bound is String.

When types are erased, the bound is used in place of the type variable, so these become simply an overload taking (and returning) Object and String parameters, respectively.

Nothing wrong with that.

like image 2
Andy Turner Avatar answered Oct 17 '22 22:10

Andy Turner