如何在Java中解决重载方法的选择歧义?

时间:2010-04-09 14:50:00

标签: java

package org.study.algos;
public class Study {

    public static void main(String[] args) {
       A a = new A();
       a.m1(null);
    }
 }
 class A {
    public void m1(String s) {
       System.out.println("String");
        System.out.println(s);
    }
    public void m1(Object obj) {
       System.out.println("Object");
       System.out.println(obj);
    }
}

此处输出为

  

的字符串   空

为什么JVM将方法解析为带有String参数的方法?

提前致谢 Ĵ

5 个答案:

答案 0 :(得分:16)

这是一个相当精细的算法,详见JLS 15.12。但与此相关的部分是15.12.2,其中说“选择最具体的部分”。 Object和String重载都是“可访问和适用的”(String是适用的,因为null文字是所有类型的引用),而String更具体。

编辑:根据语法修正部分。

答案 1 :(得分:10)

这些方法“过载”,而不是“模棱两可”。

根据Java Language Specification

  

调用方法时(第15.12节),   实际参数的数量(以及任何   显式类型参数)和   参数的编译时类型   在编译时使用   确定方法的签名   将被调用(§15.12.2)。

并且§15.12.2说:

  

可能不止一个   方法,在这种情况下最多   选择了特定的

StringObject更具体,因此虽然null与两者兼容,但选择了String参数的方法(有更复杂的规则,当参数类型是类或接口层次结构的一部分时应用。)

答案 2 :(得分:2)

null值可以设置为任何类型的引用。 您拥有的所有重载方法都在一个继承层次结构Object< - String中,正在选择最不常见的方法。 但是如果你有两个不在同一层次结构中的重载方法,那么你会得到关于ambigous方法的编译错误。

答案 3 :(得分:0)

String是Object,Object不是String,因此第一个重载比第二个重载更具体。请参阅JLS 15.12.2,作为句法提及。

答案 4 :(得分:0)

我问了一个类似的问题。 Jon Skeet写了一个很大的答案。

我的问题的链接:Which overload will get selected for null in Java?