一尘不染

Java静态导入

java

仅通过实验,我发现Java非静态方法会覆盖作用域中所有相同的命名方法,即使在静态上下文中也是如此。即使不允许参数重载。喜欢

import java.util.Arrays;    
import static java.util.Arrays.toString;

public class A {
    public static void bar(Object... args) {
        Arrays.toString(args);
        toString(args);     //toString() in java.lang.Object cannot be applied to (java.lang.Object[])
    }
}

我在规范中找不到关于此的任何信息。这是一个错误吗?如果不是,是否有任何理由实施这样的语言?

UPD:Java 6不编译此示例。 问题是-为什么?


阅读 273

收藏
2020-12-03

共1个答案

一尘不染

解释很简单,尽管它并没有改变行为非常不直观的事实:

当解析要调用的方法时,编译器要做的第一件事是找到具有正确名称的方法的最小封闭范围。只有这样,其他事情才能解决,例如过载解析和游戏中的合作。

现在,这里发生的事情是,包含toString()方法的最小封闭范围是A类,它从中继承了该方法Object。因此,我们到此为止,不要再搜索了。可悲的是,接下来,编译器将尝试在给定范围内找到最适合该方法的方法,并注意到它无法调用任何方法,并给出错误。

这意味着 永远不要 以与Object中的方法相同的名称来静态导入方法,因为 在范围内自然存在的方法优先于静态导入
(JLS详细描述了方法阴影,但是对于这个问题,我认为要简单得多)记住那个)。

编辑@alf提交了JLS的正确部分,该部分描述了想要整个图片的人的方法调用。这相当复杂,但是问题也不是那么简单,所以这是可以预期的。

2020-12-03