I totally understand the erasure of generic and therefore java cant do overloading only base on generic. But what if we take lambda expression into consideration?
See the following case.
interface base{
void test();
}
// compiler cant distinguish these two interfaces by lambda expression we provided
interface Foo extends base{}
interface Boo extends base{}
public static void main(String[] args) throws ClassNotFoundException {
HashMap<String,Long> set = new HashMap<>();
// this is valid, since type Foo is explicitly given out
t1(set,new Foo(){
@Override
public void test(){
}
}); // "Long"
// using lambda expression make the second argument indistinguishable,
//so the overloading can only depend on the first argument which is a
//Hashmap with generic type.
// but the compiler still managed to work this out
t1(set,()->{});// "Long"
HashMap<String,Integer> set2 = new HashMap<>();
t1(set2,()->{});// "Integer"
}
public static void t1(HashMap<String,Long> set,Foo foo){System.out.println("Long");}
public static void t1(HashMap<String,Integer> set,Boo boo){System.out.println("Integer");}
The result of each function call is exactly what I expected without any compile or runtime error. And that's the weired part of the whole thing: suddenly the function is overloading based on generic types.
So what is actually going on behind the scenes?