奇怪的Java的方法重载空行为[副本](Strange Java null behavior in

2019-07-19 16:28发布

这个问题已经在这里有一个答案:

  • 其过载将获得选择空在Java中? 3个回答

我有下面的代码片段:

public static void foo(Object x) {
    System.out.println("Obj");
}
public static void foo(String x) {
    System.out.println("Str");
}

如果我叫foo(null)为什么没有歧义? 为什么程序调用foo(String x)而不是foo(Object x)

Answer 1:

为什么程序调用foo(String x)而不是foo(Object x)

这是因为String类从扩展Object ,因此是更具体的Object 。 因此,编译器决定调用该方法。 请记住,编译器总是选择最具体的方法来调用。 见JLS的15.12.5节

如果不止一个成员方法既方便和适用于方法调用,就必须选择一个提供运行时方法调度描述符。 Java编程语言使用的是选择了最具体方法的规则。

非正式直觉是一种方法比另一种更具体的,如果通过第一种方法处理的任何调用可以被传递到另一个没有编译时类型错误。

但是,如果你有两个方法与参数- StringInteger ,那么你会得到ambiguity错误null ,因为编译器不能决定哪一个更具体的,因为它们是非协变类型。



Answer 2:

它调用了最具体的方法。

由于字符串是对象的一个​​子类,弦乐比对象“更具体”。



Answer 3:

  1. 的类型的null是通过定义每一个其他引用类型的子类型 。 报价JLS 4.1:

    空引用可以随时进行扩展引用转换为任何引用类型。

  2. 参与调用方法签名的分辨率如下集合中的所有兼容签名的最具体的签名的原则。 (JLS 15.12.2.5。选择最具体的方法)。

总之,这意味着String超载选择在你的榜样。



Answer 4:

当给定的两种方法,其中的参数是有效的两个参数之间进行选择,编译器总是会选择最具体的参数作为搭配。 在这种情况下, null的是,可以作为一个来处理一个文字Object和一个StringString是更具体和子类Object ,因此编译器使用它。



文章来源: Strange Java null behavior in Method Overloading [duplicate]