出于某种原因,我在执行此操作时遇到编译错误:
package mypackage2;
public class YYY {
public static void aMethod(int i, int j) {
System.out.println("aMethod with Integers: " + i + " " + j);
}
}
-
package mypackage;
import static mypackage2.YYY.*;
public class XXX {
public XXX() {
aMethod(1, 1); // <--- mypackage\XXX.java:8: error: method aMethod in class XXX cannot be applied to given types;
// aMethod(1, 1);
// ^
}
private void aMethod(String s1, String s2) {
System.out.println("aMethod with Strings: " + s1 + " " + s2);
}
public static void main(String[] args) {
new XXX();
}
}
输出:
$ javac mypackage/XXX.java mypackage2/YYY.java
mypackage\XXX.java:8: error: method aMethod in class XXX cannot be applied to given types;
aMethod(1, 1);
^
required: String,String
found: int,int
reason: actual argument int cannot be converted to String by method invocation conversion
1 error
但如果我发表评论:
private void aMethod(String s1, String s2) {
System.out.println("aMethod with Strings: " + s1 + " " + s2);
}
那么没有问题。
当您扩展另一个具有相同方法名称的类时,可以这样做,为什么在进行静态导入时这不可能?
答案 0 :(得分:1)
这实际上是预期的行为,因为在类XXX
的范围内,名称aMethod
解析为XXX.aMethod(String, String)
方法。
您应该查看JLS 6.4.1. Shadowing和JLS 15.12 Method Invocation Expression以获取解释。
阴影描述了内部作用域从外部作用域重新定义名称时的情况,因此在内部作用域内,简单名称是指内部作用域中的实体,需要完全限定名称来引用该作用域中的实体。外部范围。
静态导入在文件范围中定义aMethod
名称,XXX.aMethod
声明在aMethod
类的范围内定义XXX
名称。方法调用发生在XXX
类的范围内,因此简单名称aMethod
将解析为XXX.aMethod
。
选择方法的过程在JLS 15.12 Method Invocation Expression中描述,它包含三个步骤:
第一步涉及检查包含调用点的某个类是否具有该名称的方法。如果第一步没有找到适用的类,则在第二步 期间检查静态导入。
将其应用于您的示例:
XXX
,因为aMethod
方法的调用包含在XXX
类范围内,XXX
有一个具有该名称的方法。 XXX
搜索具有该名称的所有方法,并检查每个这样的方法是否可以应用于给定的参数列表。没有XXX.aMethod
方法可以使用(int, int)
参数,因此编译器因编译错误而停止。