【发布时间】:2020-02-06 12:43:41
【问题描述】:
鉴于此示例代码...
package example;
public class Main {
public static void main(String[] args) {
System.out.println(MyEnum.X.getValue());
}
private enum MyEnum {
X(){
@Override
String getValue() {
return toString("XYZ"); //error here
}
};
abstract String getValue();
private static String toString(String output) {
return output;
}
}
}
产生以下编译器错误:
Error:(12, 40) java: method toString in class java.lang.Enum<E> cannot be applied to given types;
required: no arguments
found: java.lang.String
reason: actual and formal argument lists differ in length
IntelliJ 有一个不同的问题:来自toString("XYZ") 的toString 带有红色下划线,并显示消息“'toString(java.lang.String)' has private access in 'example.Main.MyEnum'” ,通过“Make 'MyEnum.toString' package-private”的解决方案。
让我感到奇怪的是,以下任何一项都解决了这个问题:
- 通过枚举引用调用方法:
X.toString("XYZ")。 - 通过类引用调用方法:
MyEnum.toString("XYZ")。 - 通过 super:
super.toString("XYZ")调用方法。 (但this.toString("XYZ")不起作用) - 将方法包设为私有或公有
- 将方法命名为“toString2”
现在,对于任何生产代码,我可能会将该方法命名为其他名称(可能更能描述我对它的处理方式)并继续前进,但我仍然想知道,为什么会发生这种情况?为什么 IntelliJ 和 javac 的错误信息不同?
这个问题可能类似于Cannot make a static reference to the non-static field memberVariable with private variable,但我觉得它并不能完全解释问题——为什么重命名会起作用?
【问题讨论】:
-
@Michael 我不是在寻找快速解决方案,而是在寻找解释;为什么我需要在前面添加 MyEnum 只是因为方法名为“toString”?单独的参数应该足以区分默认 toString(0 个参数)和我自己的 toString(1 个参数)