在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()返回一个新实例。
3 回答
心有法竹
TA贡献1866条经验 获得超5个赞
如果将其分配给局部变量,则唯一可以修改的就是为此变量分配另一个枚举。这不会更改枚举本身,因为您只更改变量引用的对象。
似乎枚举实际上是单例的,因此整个程序中每个枚举只能有一个元素存在,这使==运算符对枚举合法。
因此,不存在性能问题,并且您不能意外更改枚举定义中的某些内容。
largeQ
TA贡献2039条经验 获得超7个赞
它的代码是本地的吗?还是JVM /编译器对它进行了特殊处理,仅当无法证明不会对其进行修改时才从values()返回一个新实例。
1)否。或者至少在当前的实现中没有。有关证据,请参见@lucasmo的答案。
2)AFAIK,不。
假设它可以做到这一点。但是,证明数组永远不会在本地修改对于JIT而言将是复杂且相对昂贵的。如果数组从调用的方法中“逸出” values()
,它将变得更加复杂和昂贵。
当对所有Java代码求平均值时,这种(假设的)优化可能不会奏效。
另一个问题是这种(假设的)优化可能会打开安全漏洞。
有趣的是,JLS似乎没有指定values()
成员返回数组副本。常识1说它必须做...但是实际上并没有指定。
1-如果values()
返回一个共享(可变)enum
值数组,这将是一个巨大的安全漏洞。
添加回答
举报
0/150
提交
取消