2014-12-02 69 views
5

我有以下2种方法中的一类过载:方法重载和传递null

public class Test{ 

    public static void main(String []args) throws ParseException{ 
     Test t = new Test(); 
     t.testMethod(null); 
    } 

    public void testMethod(Object o){ 
    System.out.println("Object"); 
    } 

    public void testMethod(String s){ 
    System.out.println("String"); 
    } 
} 

当我调用testMethod其打印“字符串”的方法。

当我增加一个重载的方法:

public void testMethod(StringBuilder sb){ 
    System.out.println("String"); 
} 

它抛出我的编译器错误:The method testMethod is ambigous for type Test ..

这一切时,我调用方法与null

恰好我的问题是:

  1. 为什么它打印字符串,而不是对象?
  2. 为什么在添加第三种方法时出现编译错误?
+0

除了你的具体问题,我建议你避免使用Object parm和其他具有某种特定数据类型的签名。把它作为一个整体来说可能是件好事,但它们通常是潜伏着的陷阱。 – 2014-12-02 14:17:56

回答

1

为什么它打印字符串,而不是对象?

Java编译器挑选具有最具体至少通用参数的方法。由于Object是所有班级的超班(包括String),因此挑选String班。

为什么会出现上添加第三种方法编译错误?

由于StringStringBuilder低于Object,编译器会发现呼叫暧昧因为两者StringStringBuilder可以接受null,编译器无法确定,因此你在编译过程中出现错误调用哪个方法。

如果你尝试用IOExceptionFileNotFoundException代替StringStringBuilder同样的事情,你会发现,FileNotFoundException拾取,因为它是最通用的。

3

方法解析通过选择适用于给定参数的最多特定方法来工作。在第一种情况下,String是更“特异性的”比Object(因为它是Object一个子类)等选择了String方法。

当添加另一个采用一个StringBuilder方法,既那和String方法同样“特异性的”(它们的Object直接子类),所以出现混淆哪个应被选择,因此错误。

0

在案例1字符串从Object继承,他们在继承链,空同时匹配,编译器选择一个更具体的类型 - 字符串。

在情况2字符串和StringBuilder不在继承链中的情况下,编译器不能选择更具体的类型。

JLS 15.12.2中描述了重载方法解析的细节。