在 Java 中,您可以创建一个枚举,如下所示:
public enum Letter {
A, B, C, D, E, F, G;
static {
for(Letter letter : values()) {
// do something with letter
}
}
}
这个问题涉及“values()”方法。具体是如何实施的?通常,我可以在 Eclipse 中使用 F3 或 CTRL+Click 跳转到 Java 类的源代码(甚至对于像 String、Character、Integer 甚至 Enum 这样的类)。可以查看其他枚举方法的来源(例如,valueOf(String))。
每次调用“values()”时都会创建一个新数组吗?如果我将它分配给一个局部变量,然后修改其中一个元素,会发生什么(显然这不会影响 values() 返回的值,这意味着每次分配一个新数组)。
它的代码是原生的吗?还是JVM/编译器有特殊处理,只有在不能证明不会被修改的情况下才从values()返回一个新的实例。
基本上,编译器 (javac) 在编译时将您的枚举转换为包含所有值的静态数组。当您调用 values() 时,它会为您提供此数组的 .clone'd() 副本。
鉴于这个简单的枚举:
public enum Stuff { COW, POTATO, MOUSE; }
你实际上可以看看Java生成的代码:
public enum Stuff extends Enum<Stuff> { /*public static final*/ COW /* = new Stuff("COW", 0) */, /*public static final*/ POTATO /* = new Stuff("POTATO", 1) */, /*public static final*/ MOUSE /* = new Stuff("MOUSE", 2) */; /*synthetic*/ private static final Stuff[] $VALUES = new Stuff[]{Stuff.COW, Stuff.POTATO, Stuff.MOUSE}; public static Stuff[] values() { return (Stuff[])$VALUES.clone(); } public static Stuff valueOf(String name) { return (Stuff)Enum.valueOf(Stuff.class, name); } private Stuff(/*synthetic*/ String $enum$name, /*synthetic*/ int $enum$ordinal) { super($enum$name, $enum$ordinal); } }
您可以通过创建一个临时目录并运行来查看 javac 如何“翻译”您的类: