Reputation: 525
Consider the following two method definitions:
static <T extends Do & Done>T whatToDo(T ele){return null;}
static <R extends Done & Do>R whatToDo(R ele){return null;}
Both will have the following erasures respectively:
static Do whatToDo(Do);
static Done whatToDo(Done);
Consider the concrete class Doing
and the interfaces Do
and Done
interface Do{void doIt();}
interface Done{void didIt();}
class Doing implements Do,Done{
@Override
public void doIt() {}
@Override
public void didIt() {
}
}
Now, when I try to invoke the method whatToDo
, this gives the ambiguous invocation compilation error, even though the methods got compiled in the class correctly. Only at the time of invocation, I am getting error.
public static void main(String[] args) {
whatToDo(new Doing()); //compile error : ambiguous method call
}
Does it not mean that the definition of erasure is responsible for anomaly, that only the left most element is treated as the erasure for a given bounded type? Also, why has erasure been chosen to be this way? Can there be something better for the way JLS defines the procedure of erasure?
Ideal would have been that Java shouldn't have allowed the two methods in this case to exist by modifying the definition of erasure to include the unordered set of bounds rather than just the leftmost bound?
Here is the complete code:
class Scratch {
public static void main(String[] args) {
whatToDo(new Doing());
//Compilation error : because of Erasure - the 2 definitions exist even though the
//the elements of the bounds are exactly the same
//Ideally this should have been unordered list of bounds rather than left most bound?
}
static <T extends Do & Done>T whatToDo(T ele){return null;}
static <R extends Done & Do>R whatToDo(R ele){return null;}
}
interface Do{void doIt();}
interface Done{void didIt();}
class Doing implements Do,Done{
@Override
public void doIt() {}
@Override
public void didIt() {
}
}
Upvotes: 2
Views: 50