考虑以下两组方法。第一个被接受,第二个被拒绝为含糊不清。唯一的区别是使用int和Integer。
是否特别需要拒绝第二个?这意味着在拳击之后接受它(这将导致第一组)有一个问题。我在这里想念什么?
从我的角度来看,这里的Java编译器太局限了。
设置1:
public void test(Object... values) {}
public void test(Integer x, Object... values) {} // difference here
public void b() {
test(1, "y"); // accepted
}
设置2:
public void test(Object... values) {}
public void test(int x, Object... values) {} // difference here
public void b() {
test(1, "y"); // marked as ambiguous
}
Set 2产生编译器错误:
error: reference to test is ambiguous
test(1, "y"); // marked as ambiguous
^
both method test(Object...) in T and method test(int,Object...) in T match
Java 1.8,Eclipse Oxygen
答案 0 :(得分:5)
编译器正在执行的是实现JLS 15.12.2.5中列出的规则,以便在多个方法适用于调用的情况下选择最具体的方法。在您的问题的示例中,规范中的这一行涵盖了差异:
如果
S
(§4.10),对于任何表达式,类型T
都比类型S <: T
更具体。
其中S <: T
表示S
是T
的子类型。
在示例#1中:
Integer
是Object
的子类型,因此更具体。在示例#2中:
int
不是Object
的子类型,反之亦然,因此两种类型都不比另一种更具体。 答案 1 :(得分:1)
不同之处在于,在第一种情况下,1
参数需要装入Integer,然后选择最合适的方法;那是(Integer, Object...)
版本。
在第二种情况下,有两种选择 - 拳击与否。这就是模糊不清的原因。
我同意这是违反直觉的。
答案 2 :(得分:0)
要结束这个问题,让我总结一下我理解的问题的实际答案:根据规范,行为是正确的。可以放宽规范,使原始类型作为非原始对应物被覆盖。尚未完成的一个原因是指定和实现快速正确的解析器的复杂性。