Generics ambiguity with the &-operator and order

元气小坏坏 提交于 2020-01-23 04:33:26

问题


I have a strange Java generics ambiguity behaviour that I cannot explain:

Those 3 methods in class:

public static <E extends ClassA & ClassB> void method(E val) {}
public static <E extends ClassC & ClassB & ClassA> void method(E val) {}
public static <E extends ClassB> void method(E val) {}

compile fine.

But those not (ambiguity violation):

public static <E extends ClassA & ClassB> void method(E val) {}
public static <E extends ClassB & ClassC & ClassA> void method(E val) {}
public static <E extends ClassB> void method(E val) {}

(ClassA, ClassB, ClassC are all completely independent interfaces!)


回答1:


Due to type erasure, the compiler needs to pick a statically-known type for the parameter type in the compiled method.

To do this, it uses the first type in your constraint list.

In your first example, this results in a unique type for each method, so it compiles to

public static method(ClassA val);
public static method(ClassC val);
public static method(ClassB val);

This is perfectly legal (except for your missing return type); it creates three overloads with three different parameter types.

In your second example, this creates an ambiguity:

public static method(ClassA val);
public static method(ClassB val);
public static method(ClassB val);

This is not legal, because the last two methods have the same signature.

The spec explicitly documents this behavior.

This could have been made legal by trying to pick a single constraint type from each overload such that there are no conflicts, but that would be complicated & slow for larger constraint lists.
The spec could have said something like:

If it is used in erasure of a type in the parameter list, the erasure of a type variable in a generic method is chosen such that each overload of that method results in a unique signature after erasure.
If no combination of erasures will result in a unique signature, an ambiguity error occurs.

I suspect that this problem is in NP.




回答2:


It is defined in the JLS #4.6:

The erasure of a type variable is the erasure of its leftmost bound.

And if two methods have the same erasure, the compiler gives you an error.



来源:https://stackoverflow.com/questions/21142467/generics-ambiguity-with-the-operator-and-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!