我在类中重载了以下两种方法:
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
我的问题是:
答案 0 :(得分:3)
方法解析的工作原理是选择适用于给定参数的大多数特定方法。在第一种情况下,String
比Object
更“具体”(因为它是Object
的子类),因此选择了String
方法。
当您添加另一个采用StringBuilder
的方法时,该方法和String
方法同样是“特定的”(它们都是Object
的直接子类),所以有一个应该选择哪个模糊,因此错误。
答案 1 :(得分:1)
为什么打印String而不是Object?
java编译器使用最具体的或最不通用的参数选择方法。由于Object
是所有类的超类(包括String
),因此选择String
类。
为什么添加第三种方法会出现编译错误?
由于String
和StringBuilder
低于Object
,编译器会发现调用不明确,因为String
和StringBuilder
可以接受null
,编译器无法确定调用哪个方法,因此在编译期间会出错。
如果您使用IOException
和FileNotFoundException
代替String
和StringBuilder
尝试相同的操作,您会发现FileNotFoundException
被选中,因为它是最不通用的。
答案 2 :(得分:0)
在case1中,String继承自Object,它们在继承链中,null匹配两者,编译器选择更具体的类型 - String。
如果2 String和StringBuilder不在继承链中,编译器就无法选择更具体的类型。
JLS 15.12.2中描述了重载方法解析的详细信息。