java - 如何为 Java 6 枚举实现 values()?

标签 java enums

在 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

关于java - 如何为 Java 6 枚举实现 values()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1163076/

相关文章:

java - 无法解析 : com. android.support.test.espresso :espresso-intents:27. 0.2

java - 如何使用 Javadoc @link 到枚举值

c# - 关于 Enum 和 DataAnnotation

typescript - 在 Typescript 对象中提取 ENUM 的字符串值

postgresql - 使用一个命令添加多个 PostgreSQL 枚举值

java - 为什么我可以从另一个包访问非公共(public) javax.swing.Box.Filler?

java - 从 Java 调用存储过程 - Spring JDBC 的现代替代品?

Java : Getting effected sentence in Google-diff-match-patch

ios - 存储在枚举中的变量的动态值

java - 摆脱枚举中的代码重复