gpt4 book ai didi

java - Enum 的匿名实现无法使用参数引用 Enum 的私有(private)静态 toString

转载 作者:行者123 更新时间:2023-12-03 03:09:22 25 4
gpt4 key购买 nike

鉴于此示例代码...

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)”显示了“在 'example.Main.MyEnum' 中具有私有(private)访问权限”,以及“使 'MyEnum.toString' 包私有(private)”的解决方案。

对我来说奇怪的是,以下任何一项都可以解决此问题:

  • 通过枚举引用调用方法:X.toString("XYZ")
  • 通过类引用调用方法:MyEnum.toString("XYZ")
  • 通过 super 调用该方法:super.toString("XYZ")。 (但是 this.toString("XYZ") 不起作用)
  • 将方法设为包私有(private)或公开
  • 将方法命名为“toString2”

现在,对于任何生产代码,我可能会将该方法命名为其他名称(可能更能描述我将用它做什么)并继续,但我仍然想知道,为什么会发生这种情况?为什么 IntelliJ 和 javac 的错误消息不同?

这个问题可能类似于 Cannot make a static reference to the non-static field memberVariable with private variable ,但我觉得它并不能完全解释问题 - 为什么重命名有效?

最佳答案

首先,这个问题并不是枚举所特有的。它适用于任何内部类。我重构了您的示例以删除枚举,这演示了内部类和匿名内部类存在相同的问题。

class Main {
public static void main(String[] args) {
Main main = new Main() {
{
System.out.println(toString("XYZ")); // same error
}
};
}

class Foo {
{
System.out.println(toString("XYZ")); // same error
}
}

private static String toString(String output) {
return output;
}
}

在 JLS here 中进行了解释:

Example 6.5.7.1-1. Simple Method Names

The following program demonstrates the role of scoping when determining which method to invoke.

class Super {
void f2(String s) {}
void f3(String s) {}
void f3(int i1, int i2) {}
}

class Test {
void f1(int i) {}
void f2(int i) {}
void f3(int i) {}

void m() {
new Super() {
{
f1(0); // OK, resolves to Test.f1(int)
f2(0); // compile-time error
f3(0); // compile-time error
}
};
}
}

For the invocation f1(0), only one method named f1 is in scope. It is the method Test.f1(int), whose declaration is in scope throughout the body of Test including the anonymous class declaration. §15.12.1 chooses to search in class Test since the anonymous class declaration has no member named f1. Eventually, Test.f1(int) is resolved.

For the invocation f2(0), two methods named f2 are in scope. First, the declaration of the method Super.f2(String) is in scope throughout the anonymous class declaration. Second, the declaration of the method Test.f2(int) is in scope throughout the body of Test including the anonymous class declaration. (Note that neither declaration shadows the other, because at the point where each is declared, the other is not in scope.) §15.12.1 chooses to search in class Super because it has a member named f2. However, Super.f2(String) is not applicable to f2(0), so a compile-time error occurs. Note that class Test is not searched.

For the invocation f3(0), three methods named f3 are in scope. First and second, the declarations of the methods Super.f3(String) and Super.f3(int,int) are in scope throughout the anonymous class declaration. Third, the declaration of the method Test.f3(int) is in scope throughout the body of Test including the anonymous class declaration. §15.12.1 chooses to search in class Super because it has a member named f3. However, Super.f3(String) and Super.f3(int,int) are not applicable to f3(0), so a compile-time error occurs. Note that class Test is not searched.

Choosing to search a nested class's superclass hierarchy before the lexically enclosing scope is called the "comb rule" (§15.12.1).

关于java - Enum 的匿名实现无法使用参数引用 Enum 的私有(private)静态 toString,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60095314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com