为什么具有相同名称的静态方法的静态导入是合法的?

2022-09-01 11:52:41

假设我们有这些包和类:

package p1;

public class A1 {
    public static void a() {}
}

package p2;

public class A1 {
    public static void a() {}
}

package p3;

import static p1.A1.a;
import static p2.A1.a;

public class A1 {
    public static void test() {

    }
}

我想知道,为什么静态导入方法在包中是合法的(不会导致编译时错误)?我们将无法在方法中进一步使用它们,因为这种用法将导致编译时错误。p3test()

为什么它与类的正常导入不同。假设我们想从包中导入类并导入到:A1p1p2p3

package p3;
import p1.A1;
import p2.A1;

这样的导入是非法的,会导致编译时错误。


答案 1

方法静态导入的模糊性可以在方法调用时解决。

例如,如果您有两个如下所示的方法的静态导入:

void frobnicate(int i);
// and
void frobnicate(boolean b);

然后,您可以导入并使用两者,因为编译器可以根据您传入的参数(调用第一个参数,调用第二个参数)来判断要使用哪个参数。frobnicate(1)frobnicate(true)

对于类,这是不可能的:仅靠这一点不足以告诉你想要两个类中的哪一个。Foobar a;Foobar

另请注意,单个静态导入可以导入多个名称。根据JLS的相关部分(强调我的):

单静态导入声明从类型中导入具有给定简单名称的所有可访问静态成员。

例如,如果上述两个方法位于同一类中,则单个导入可以同时导入它们。frobnicatestatic


答案 2

这是因为您已经将所有这些类命名为相同的内容。每次调用此静态方法时,它都会在最局部的类中查找,在本例中是 p3 中的 A1,它不包含静态方法 a()。永远记住,一个类名应该是唯一的,永远不要与另一个相同。