当前位置: 首页 > 知识库问答 >
问题:

方法重载中奇怪的Java空行为[重复]

黄锋
2023-03-14

我有以下代码片段:

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

如果我调用foo(null)为什么没有歧义?为什么程序调用foo(字符串x)而不是foo(对象x)?

共有3个答案

邹英悟
2023-03-14

它在调用最具体的方法

由于String是Object的子类,所以String比Object“更具体”。

谈秦斩
2023-03-14

>

  • null的类型根据定义是所有其他引用类型的子类型。引用JLS 4.1:

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

    调用中涉及的方法签名的解析遵循所有兼容签名集中最具体签名的原则。(JLS15.12.2.5.选择最具体的方法)。

    这意味着在您的示例中选择了重载。

  • 宋劲
    2023-03-14

    为什么程序调用foo(字符串x)而不是foo(对象x)

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

    如果多个成员方法既可访问又适用于方法调用,则需要选择一个来为运行时方法调度提供描述符。Java编程语言使用选择最具体方法的规则。

    非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个方法,而不会出现编译时类型错误,那么一个方法比另一个方法更具体。

    但是,如果您有两个带有参数的方法-StringIntger,那么您将获得null歧义错误,因为编译器无法决定哪一个更具体,因为它们是非协变类型。

     类似资料:
    • 通常,具有固定参数数的方法优于具有可变参数数的重载方法。但是,该示例的行为不同: 输出: main的第三行用一个参数调用该方法,该参数是一个包含两个元素的字符串[]。但这并不是用一个参数执行方法,而是执行varargs方法,就像我给了它两个参数一样(这有点正常,因为它是一个数组)。 现在的问题是:这应该发生吗?我是否发现了错误或未记录的行为?它这样做的原因是什么? 我为什么这么做:我想做一个快捷方

    • 为什么第一次计算的结果比第二次计算的结果大? 结果:

    • null 结果将是0xFFFFFFFFFFFFFFFF0000(正确,寄存器溢出,但我们只更改2字节) 结果将为0x00000000000000000000(WTF?,寄存器溢出,但结果更改所有8个字节而不是4个字节。为什么是0x00000000000000,而不是0xFFFFFF00000000)

    • 问题内容: 到处都写着静态方法不能被覆盖,但是当我尝试将访问说明符从public改为protected时,它给出了一个错误。例如 它说 无法降低继承方法的可见性 所以说这是遵循最重要的规则,为什么我们说foo在B类中没有被忽略?为什么我们说它是隐藏/阴影而不是覆盖? 问题答案: 它 遵循 与覆盖 相同 的 一些规则 ,但这并不意味着它 被 覆盖。在这种情况下,这就是JLS的8.4.8.3节 “覆盖

    • 但是,我犯了一个错误,写了这样一段话: 然后我写道: 没有打印任何输出,所以我的问题是,基本上,为什么?

    • 我正在尝试改变鼠标按钮,将地图视图从右键平移到左键。 在单击鼠标左键后,有一个简单的代码来更改按钮: 如何直接改变平移按钮,而不被释放和再次点击?谢谢你的帮助...