我有一个快速而直接的问题:
我有这个简单的课程:
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);
}
}
更新:实际上是实际调用Number的方法。 对不起,我很困惑。
如果我调用a.m(null),它将使用Number参数调用方法。
我的问题是:为什么? 在Java语言规范中的哪个位置?
...因为null不是Number对象,因此它属于更通用的Object存储桶。
那很有趣,因为在我的机器上(在eclipse上运行),它始终默认为Number方法
+1有趣的问题
-1这是重载,而不是覆盖
首先,它实际上调用m(Number)。
发生这种情况是因为这两种方法均适用,但是m(Number)是最具体的方法,因为m(Number)的任何参数都可以传递给m(Object),反之亦然。
如果将m(Object)替换为m(String)(或添加其他方法,例如m(Date)),则编译器将报告歧义,因为无法识别最特定的方法。
请参阅" Java规范"中的"选择最特定的方法"部分。
好的,既然我已经运行了示例代码,我也看到了。 同样有意义的是,一旦我添加了m(Date n){...},我就会得到一个错误:"方法m(Object)对于该类型来说是不明确的"
这不是多态或覆盖。这是方法重载。
我对此进行了测试,并调用了特定方法(不是m(Object)),并且根据规范始终调用特定方法。 Java中将为空选择哪个重载?
+1表示覆盖和过载之间的区别
+1以突出显示这是超载
您需要考虑的另一个相关问题:
public static void main(String[] args)
{
A a = new A();
Object n = new Integer(1);
a.m(n); // which method will be called?
}
将调用"带有对象的m",但我不知道为什么。 谁能解释? 凭直觉,我以为会打印出"带有数字的m",但是……不。
我的2美分。带有Number参数的方法被称为,因为Number扩展了Object。过去我也遇到过类似的情况,我确实重写了一个方法,并将Component代替了JComponent(错误地)。我花了一个星期的时间才找到从未调用我的方法的原因。我弄清楚,如果重载的方法之间存在某种继承关系,则JVM首先匹配类层次结构中的更深层次的方法。
Object是Java中的默认类型。如果将m(Object o)方法重构为m(String o),则会出现编译时错误,表明调用m(null)模棱两可,因为Java无法确定String和Number之间的哪个类默认为null
除此之外,在m(Object o)和m(Number o)之间,调用m(null)将调用m(Number o),因为它是最专门的方法。否则,您需要将null强制转换为Object(或任何不是Number实例的内容)。
a.m((String) null);
null没有类型,它调用m(Number)
好吧……正式有一个空类型,它是所有引用类型的子类型。 很奇怪。