因为它是模棱两可的。
2 可以是Integer 和long,并且可以同时解析两者。你让编译器混淆了调用谁:)
5.12.2.2 选择最具体的方法
如果有多个方法声明
既可访问又适用于
方法调用,需要
选择一个来提供描述符
用于运行时方法分派。这
Java 编程语言使用
规则,最具体的方法是
选择。非正式的直觉是
一种方法声明更多
如果有的话,比另一个更具体
第一种方法处理的调用
可以传给另一个
没有编译时类型错误。
具体定义如下。
让 m 是一个名字并假设有
是两个命名方法的声明
m,每个都有 n 个参数。认为
一个声明出现在一个
类或接口 T 并且
参数类型为 T1, . . .
, Tn;此外,假设另一个
声明出现在一个类中或
接口 U 和类型
参数为 U1, 。 . . ,联合国。然后
在 T 中声明的方法 m 更
比在中声明的方法 m 更具体
U 当且仅当同时满足以下两个条件
是真的:
T可以通过方法转换为U
调用转换。 Tj 可以是
通过方法调用转换为 Uj
转换,对于从 1 到 n 的所有 j。一种
方法被称为最大
特定于方法调用,如果它
适用且可访问并且存在
没有其他适用和可访问的
更具体的方法。如果有
正是一个最具体的
方法,那么它其实是最
具体方法;这是必然的
比任何其他方法更具体
这是适用和可访问的。它
然后受到一些进一步的
编译时检查,如中所述
§15.12.3.
可能没有方法是
最具体的,因为有两个
或更具体的方法。在
本例:
如果所有最大特定的方法
具有相同的签名,则:如果一个
最具体的方法是
没有声明抽象,它是最
具体方法。否则,所有
最具体的方法是
必须声明为抽象的。这
选择最具体的方法
在最大的任意之间
具体方法。然而,最
具体方法考虑抛出
一个检查的异常当且仅当
该异常在
throws 的每个子句
最具体的方法。否则,
我们说方法调用是
模棱两可,编译时错误
发生。
15.12.2.3 示例:重载歧义
Consider the example:
class Point { int x, y; }
class ColoredPoint extends Point { int color; }
class Test {
static void test(ColoredPoint p, Point q) {
System.out.println("(ColoredPoint, Point)");
}
static void test(Point p, ColoredPoint q) {
System.out.println("(Point, ColoredPoint)");
}
public static void main(String[] args) {
ColoredPoint cp = new ColoredPoint();
test(cp, cp); // compile-time error
}
}
此示例在编译时产生错误。问题是有两个适用和可访问的测试声明,并且没有一个比另一个更具体。因此,方法调用是模棱两可的。
如果添加了第三种测试定义:
static void test(ColoredPoint p, ColoredPoint q) {
System.out.println("(ColoredPoint, ColoredPoint)");
}
那么它会比其他两个更具体,方法调用将不再模棱两可。