在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如何“翻译”你的类:
javac -d <output directory> -XD-printflat filename.java