多态和方法重载

我有一个快速而直接的问题:

我有这个简单的课程:

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? am(null); } } 

更新:实际上是实际调用Number的方法。 对此感到抱歉。

如果我调用am(null),则使用Number参数调用方法。

我的问题是:这是为什么? 这个指定的java语言规范在哪里?

首先,它实际上调用m(Number)

这是因为两种方法都适用 ,但m(Number)最具体的方法,因为m(Number)任何参数都可以传递给m(Object) ,反之则不然。

如果用m(String)替换m(Object) (或添加其他方法,如m(Date) ),编译器将报告歧义,因为无法识别最具体的方法。

请参阅Java规范中选择最具体方法一节。

  1. 这不是多态或覆盖。 这是方法重载
  2. 我测试了这个并且调用了特定的方法(不是m(Object)),并且根据规范总是调用特定的方法。 在Java中为null选择哪个重载?

另一个相关问题供您考虑:

 public static void main(String[] args) { A a = new A(); Object n = new Integer(1); am(n); // which method will be called? } 

我的2美分。 带有Number参数的方法是被调用的方法,因为Number扩展了Object。 我过去有过类似的情况,我确实覆盖了一个方法,并且放置了Component而不是JComponent(错误地)。 我花了一个星期才找出我的方法从未被调用的原因。 我弄清楚,如果重载方法之间存在一些inheritance关系,那么JVM首先匹配类层次结构中较深的一个。

Object是Java中的默认类型。 如果将m(Object o)方法重构为m(String o) ,则会发生编译时错误,指出调用m(null)是不明确的,因为Java无法确定StringNumber之间的哪个类默认为null

除此之外,在m(Object o)m(Number o) ,调用m(null)将调用m(Number o)因为它是最专业的方法。 您需要将null转换为Object (或任何不是Number的实例)。

 am((String) null);