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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (45)

在Java中,您可以创建一个枚举,如下所示:

public enum Letter {
    A, B, C, D, E, F, G;

    static {
       for(Letter letter : values()) {
          // do something with letter
       }
    }
}

这个问题涉及“values()”方法。具体来说,它是如何实施的?通常,我可以使用F3或CTRL +在Eclipse中跳转到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
用户回答回答于

如果将其分配给局部变量,则唯一可以修改的是将另一个枚举分配给此变量。这不会改变枚举本身,因为你只是改变对象的变量引用。

看起来枚举实际上是单例,所以每个枚举中只有一个元素可以存在于整个程序中,这使得==运算符对于枚举是合法的。

所以没有性能问题,你不能无意中改变你的枚举定义中的某些东西。

扫码关注云+社区