gpt4 book ai didi

java - 为什么这个枚举编译?

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:33 25 4
gpt4 key购买 nike

我想创建一个 enum,其中每个常量都有一个与之关联的 Map。我通过为每个常量提供一个实例初始化程序来实现这一点,如下所示:

import java.util.HashMap;
import java.util.Map;

public enum Derp {
FOO {{
mMap.put("bar", 1);
}};

// cannot be private
protected final Map<String, Integer> mMap = new HashMap<>();
}

我发现如果mMapprivate,它就不能在实例初始化器中被引用。错误是 Cannot make a static reference to the non-static field mMap。在我想到这个原因之前,我咨询了JLS §8.9.2 ,部分内容是:

It is a compile-time error for the constructors, instance initializer blocks, or instance variable initializer expressions of an enum constant e to refer to e or to an enum constant of the same type that is declared to the right of e.

我在 FOO 自己的实例初始化器中隐式引用 FOO 不是违反了这个规则吗?这是如何编译的?它不仅可以编译,而且可以在运行时正常工作。

(我想到 mMap 不能是 private 因为我隐式创建了一个匿名子类,它不能引用 private 字段它的父类(super class)。这本身有点奇怪,因为枚举隐式地 final...)

最佳答案

It is a compile-time error for the constructors, instance initializer blocks, or instance variable initializer expressions of an enum constant e to refer to e or to an enum constant of the same type that is declared to the right of e.

这里的规范只是意味着你不能通过name 来引用,因为e 所引用的字段还没有初始化。这并不意味着您无法访问 this

它基本上与任何其他初始化程序(如 int x = x;)的规则相同。

我们可以通过类似 ( Ideone) 的示例了解原因:

enum Example {
INSTANCE {{
subversion();
}};

static void subversion() {
System.out.println(INSTANCE);
}

public static void main(String[] args) {
System.out.println(INSTANCE);
}
}

哪些输出

null
INSTANCE

I found that if mMap is private, it cannot be referenced in the instance initializer.

您可以将调用限定为 super.mMap.put(...);。私有(private) mMap 不是继承的,但可以从内部类访问。 I also covered this here .简而言之,简单名称 mMap 指的是 Derp 的不存在的外部实例。

我们可以通过类似 ( Ideone) 的示例来验证情况是否如此:

class Example {
private int x;

class Inner extends Example {{
x = 1; // refers to the outer instance
super.x = 2; // refers to the inner instance
}}

public static void main(String[] args) {
Example outer = new Example();
Example inner = outer.new Inner();
System.out.println(outer.x); // prints 1
System.out.println(inner.x); // prints 2
}
}

除了你的情况 FOO 是静态的,所以没有外部实例——因此编译器错误。

关于java - 为什么这个枚举编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29641012/

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