Enum.values() 从何而来?
我正在查看文档和源代码,因为我想确定 value() 总是按照声明 Enum 值的顺序返回一个数组。事实证明,据我所知,它不在文档中。
我检查了 Enum 类的源代码,但没有运气(那里是一个相关的私有“getValues”方法)。
所以我猜测某些编译器/解释器-foo 已经在继续创建一个类,该类将 Enum 扩展为如下声明:
public static enum MyEnum
那么,values() 在编译期间是否也静态转换为硬编码数组?或者它实际上是一个在运行时调用的方法,如果是的话,它是在哪里定义的?
I was looking through the documentation and source code, because I wanted to be certain that values() would always return an array in the order in which the Enum values are declared. Turns out, it's not in the documentation as far as I can tell.
I checked the source code for the Enum class, and no luck (there is a related, private "getValues" method).
So I'm guessing that some compiler/interpreter-foo is already going on to create a class that extends Enum out of a declaration like:
public static enum MyEnum
So is values() also statically translated into a hardcoded array during compilation? Or is it actually a method called at runtime, and if so, where is it defined?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
values()
方法是enum
类型定义的一部分。不要与Enum
基类混淆。正式定义位于 JLS 第 8.9 节 确实指定返回的顺序与声明它们的顺序相匹配。The
values()
method is part of the definition of theenum
type. Not to be confused with theEnum
base class. The formal definition is in the Section 8.9 of the JLS which does specify the order returned matches the order in which they are declared.正如您从下面通过反汇编枚举获得的字节码中看到的,枚举上的
values()
方法只是返回一个private static
数组的副本,其中包含所有声明的枚举常量。该数组ENUM$VALUES
填充在静态初始化块中。DaysOfTheWeek.java
DaysOfTheWeek.java 反汇编
在静态块之后,标记为 0-92 的字节码初始化枚举常量,标记为 94-139 的字节码将这些常量放入数组中并标记为 140 的字节码将数组分配给类的
ENUM$VALUES
静态字段。values()
方法中的代码只是通过调用System.arraycopy
来创建分配给ENUM$VALUES
字段的数组的副本并返回副本。As you can see from the bytecode below obtained by disassemlbing an enum, the
values()
method on the enums simply return a copy of theprivate static
array which contains all the declared enum constant. This arrayENUM$VALUES
is filled in a static initilization block.DaysOfTheWeek.java
DaysOfTheWeek.java disassembled
After the static block, the bytecode marked 0-92 initializes the enum constants, the bytecode marked 94-139 puts those constants in an array and the bytecode marked 140 assigns the array to the
ENUM$VALUES
static field of the class. The code in thevalues()
method simply creates a copy of the array assigned to theENUM$VALUES
field by callingSystem.arraycopy
on it and returns the copy.我将补充 Devon 的答案,即
values()
方法是由编译器根据定义添加的。从枚举教程:
I'll add to Devon's answer, that the
values()
method is added by the compiler, by definition.From the enums tutorial:
您提供的链接(其中有一个私有
getValues
方法)来自 Apache Harmony (版本 6,这是一个开源 Java SE)。它们与 Oracle 的Enum
类(没有私有getValues
方法)有不同的实现。Oracle java(撰写本文时版本为 1.6.0-21)具有
valueOf(ClassenumType, String name)
。这是它的实现:本质上,这是 Apache 实现其
valueOf
的不同之处。Enum
(或enum
)有一个名为values()
的公共静态方法,它返回在enum
中声明的枚举值常量代码>.这是由编译器填充的。Your link you provided (where there's a private
getValues
method) is from Apache Harmony (version 6, which is an open source Java SE). They have a different implementation to Oracle'sEnum
class (which has no privategetValues
method).The Oracle java (version 1.6.0-21 at the time of writing) has the
valueOf(Class<T> enumType, String name)
. Here's its implementation:In essence, it's how Apache implemented their
valueOf
that's different.Enum
(orenum
) have a public static method calledvalues()
that returns the enumerated values constants declared inside theenum
. That's populated by the compiler.