我有一个快速而直接的问题:
我有这个简单的课程:
public class A
{
public void m(Object o)
{
System.out.println("m with Object called");
}
public void m(Number n)
{
System.out.println("m with Number called");
}
public static void main(String[] args)
{
A a = new A();
// why will m(Number) be called?
a.m(null);
}
}
UPDATE:实际上是实际调用Number的方法。对此感到抱歉。
如果我调用a.m(null),则使用Number参数调用方法。
我的问题是:这是为什么?这个指定的java语言规范在哪里?
答案 0 :(得分:26)
首先,它实际上调用了m(Number)
。
之所以发生这种情况,是因为这两种方法都适用,但m(Number)
是最具体的方法,因为m(Number)
的任何参数都可以传递给m(Object)
,但反之亦然。
如果您将m(Object)
替换为m(String)
(或添加其他方法,例如m(Date)
),则编译器会报告歧义,因为无法识别最具体的方法。
请参阅Java规范中的Choosing the Most Specific Method部分。
答案 1 :(得分:12)
答案 2 :(得分:7)
另一个相关问题供您考虑:
public static void main(String[] args)
{
A a = new A();
Object n = new Integer(1);
a.m(n); // which method will be called?
}
答案 3 :(得分:1)
我的2美分。带有Number参数的方法是被调用的方法,因为Number扩展了Object。我过去有过类似的情况,我确实覆盖了一个方法并且放置了Component而不是JComponent(错误地)。我花了一个星期才找出为什么我的方法从未被调用过的原因。我想通了,如果重载方法之间存在一些继承关系,那么JVM首先匹配类层次结构中较深的一个。
答案 4 :(得分:0)
Object
是Java中的默认类型。如果您将m(Object o)
方法重构为m(String o)
,则会出现编译时错误,表示调用m(null)
不明确,因为Java无法确定String
和{{之间的哪个类1}}默认为Number
除此之外,在null
和m(Object o)
之间,调用m(Number o)
会调用m(null)
,因为它是最专业的方法。您需要将m(Number o)
转换为null
(或任何不是Object
的实例)。
Number