请考虑以下两个简单的Java代码段:
import java.util.Arrays;
class Okay {
public static void main(String... args) {
System.out.println(Arrays.toString(new int[0]));
}
}
这很好。但是,如果我经常使用toString,可能会很想使用静态导入,例如:
import static java.util.Arrays.toString;
class DoesNotCompile {
public static void main(String... args) {
System.out.println(toString(new int[0]));
}
}
如果尝试这种方法,Java会认为我正在尝试从Object调用toString(),然后抱怨toString没有参数。这似乎很愚蠢:我处于静态方法中,因此甚至不应考虑toString。 (即使在实例方法中,我也认为Java应该在这里得到正确的答案。)
有什么办法可以解决此问题,或者如果该名称已被“采用”,那么静态导入是否不起作用?
没有,这没有办法。
[[从JLS 15.12开始,方法调用表达式](https://docs.oracle.com/javase/specs/jls/se14/html/jls-15.html#jls-15.12)(更具体地说,来自15.12.1,“确定要搜索的类或接口”)]
如果表单是MethodName,即只是一个标识符,则:
如果标识符以该名称(第6.3节,第6.4.1节)出现在方法声明的范围内,则:
如果存在一个封闭的类型声明,该方法是该方法的成员,则让T为最里面的这种类型声明。搜索的类或接口是T。
此搜索策略称为“梳子规则”。在嵌套类及其父类层次结构中查找方法之前,它有效地在嵌套类的父类层次结构中查找方法。有关示例,请参见第6.5.7.1节。
否则,由于一个或多个单静态导入或按需静态导入声明,方法声明可能会在范围内。没有要搜索的类或接口,因为稍后将确定要调用的方法(第15.12.2.1节)。
因此,“本地”方法将始终在静态导入之前匹配。