java调用看起来模棱两可,但在意外的输出下运行得很好
请看这个Java类
class Demo
{
public static void a(String s)
{
System.out.println("string called");
}
public static void a(Object a)
{
System.out.println("Object called");
}
public static void main(String...asrgs)
{
a(null);
}
}
这段代码的输出是“stringcalled”,但我无法理解编译器如何在对象和字符串之间解析
此外,请检查此代码片段
class Demo
{
public static void a(String s)
{
System.out.println("string called");
}
public static void a(Integer n)
{
System.out.println("number called");
}
public static void a(Object a)
{
System.out.println("Object called");
}
public static void main(String...asrgs)
{
a(null);
}
}
这里我们得到了一个与不明确调用相关的编译时错误(这是很明显的)。 有什么好的解释吗
# 1 楼答案
答案在于§15.12.2的JLS:
(我的重点)
。。。和§15.12.2.5,上面一节提到的,它有专一性规则的全部细节,但也有这个方便的摘要:
在第一个示例中,
a(String)
比a(Object)
更具体,因此编译器知道使用哪一个,并且很高兴。在第二个示例中,a(String)
和a(Integer)
都比a(Object)
更具体,但两者都适用于null
,并且它们处于不同的谱系中(String
是String > Object
,Integer
是Integer > Number > Object
),这造成了编译器抱怨的歧义如果他们在相同的谱系中,就不会有歧义,因为只有一个适用的最具体的选项。例如:
它打印
"GrandChild"
,因为a(Child)
和a(GrandChild)
都比a(Object)
更具体,而a(GrandChild)
比a(Child)
更具体