考虑以下两组方法。第一个被接受,第二个被拒绝为模棱两可。唯一的区别是使用int和Integer。
有没有特别需要拒绝第二个?这意味着在装箱后接受它(这将导致第一组)有一个问题。我在这里错过了什么?
在我看来,Java编译器在这方面的限制太大了。
Set 1:
public void test(Object... values) {}
public void test(Integer x, Object... values) {} // difference here
public void b() {
test(1, "y"); // accepted
}Set 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 matchJava 1.8,Eclipse Oxygen
发布于 2017-09-04 21:26:02
编译器所做的是实现JLS 15.12.2.5中设置的规则,以便在多个方法适用于调用的情况下选择最具体的方法。在您的问题中的示例中,规格中的这一行涵盖了差异:
对于任何表达式if
S <: T,类型S比类型T更具体(§4.10)。
其中,S <: T表示S是T的子类型。
在示例1中:
Integer是Object的子类型,因此它更具体第二种方法比first.在示例2中:
int不是Object的子类型,反之亦然,因此这两种类型都不比另一种更具体。因此,这两种方法都比other.发布于 2017-09-04 21:22:52
不同之处在于,在第一种情况下,需要将1参数装箱到整数中,然后选择最合适的方法;即(Integer, Object...)版本。
在第二种情况下,有两个选项-装箱或不装箱。这就是它的模棱两可的原因。
我同意这是违反直觉的。
发布于 2017-09-11 14:51:24
为了结束这个问题,让我总结一下我所理解的问题的实际答案:根据规范,行为是正确的。该规范可以放宽,使得原始类型作为它们的非原始对等类型被涵盖。一个尚未完成的原因是指定和实现一个快速而正确的解析器的复杂性。
https://stackoverflow.com/questions/46037767
复制相似问题