泛型的引用不明确
我在这里遇到了一个非常棘手的泛型和方法重载的情况。看看这个示例类:
public class Test {
public <T> void setValue(Parameter<T> parameter, T value) {
}
public <T> void setValue(Parameter<T> parameter, Field<T> value) {
}
public void test() {
// This works perfectly. <T> is bound to String
// ambiguity between setValue(.., String) and setValue(.., Field)
// is impossible as String and Field are incompatible
Parameter<String> p1 = getP1();
Field<String> f1 = getF1();
setValue(p1, f1);
// This causes issues. <T> is bound to Object
// ambiguity between setValue(.., Object) and setValue(.., Field)
// is possible as Object and Field are compatible
Parameter<Object> p2 = getP2();
Field<Object> f2 = getF2();
setValue(p2, f2);
}
private Parameter<String> getP1() {...}
private Parameter<Object> getP2() {...}
private Field<String> getF1() {...}
private Field<Object> getF2() {...}
}
上面的例子在Eclipse(Java 1.6)中完美地编译,但不是使用Ant javac命令(或JDK的javac命令),在那里我在第二次调用时收到这种错误消息:setValue
对 setValue 的引用是模棱两可的,两种方法 setValue(org.jooq.Parameter,T) 在 Test 中和 method setValue(org.jooq.Parameter,org.jooq.Field) 在 Test match 中
根据规范和我对Java编译器工作原理的理解,应该始终选择最具体的方法:http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#20448
无论如何,即使绑定到 ,这使得这两种方法都可以接受调用,但具有参数的方法似乎总是更具体。它适用于Eclipse,只是不适用于JDK的编译器。<T>
Object
setValue
Field
更新:
像这样,它可以在Eclipse和JDK编译器中工作(当然,带有rawtypes警告)。我理解,当涉及泛型时,规范中指定的规则非常特殊。但我发现这相当令人困惑:
public <T> void setValue(Parameter<T> parameter, Object value) {
}
// Here, it's easy to see that this method is more specific
public <T> void setValue(Parameter<T> parameter, Field value) {
}
更新 2:
即使使用泛型,我也可以创建此解决方法,通过添加一个名为 .这让我认为 to 的绑定才是真正导致这里所有麻烦的原因:<T>
Object
setValue
setValue0
T
Object
public <T> void setValue(Parameter<T> parameter, T value) {
}
public <T> void setValue(Parameter<T> parameter, Field<T> value) {
}
public <T> void setValue0(Parameter<T> parameter, Field<T> value) {
// This call wasn't ambiguous in Java 7
// It is now ambiguous in Java 8!
setValue(parameter, value);
}
public void test() {
Parameter<Object> p2 = p2();
Field<Object> f2 = f2();
setValue0(p2, f2);
}
我在这里误解了什么吗?是否存在与此相关的已知编译器错误?或者是否有解决方法/编译器设置来帮助我?
后续:
对于那些感兴趣的人,我已经向Oracle和Eclipse提交了一份错误报告。甲骨文已经接受了这个错误,到目前为止,Eclipse已经分析了它并拒绝了它!看起来我的直觉是正确的,这是一个错误javac