Java Enums – 在枚举上切换语句与访问者模式 – 性能优势?

我一直在寻找这个基于性能的问题的答案。
到目前为止,在挖掘了互联网之后,我了解到有几种方法可以在java中使用Enums, 这里有详细记载。 好吧,作为一个初学者,我希望在switch-case语句中使用Enums,这样可以提供清晰度并更好地理解代码。 但另一方面,我们还有一个访问者模式样式的Enums实现,它确保了类型的安全性和可扩展性, 这里讨论。

话虽如此,并回到这个问题背后的原始想法,到目前为止,我已经了解到如果使用Enums正确设计switch-case结构,这确保了case值不稀疏,并且Enum声明是相同的编译单元作为switch-case语句,java编译器通过实现跳转表这样的构造对生成的字节码执行一些优化(在这里和其他地方讨论过,在Sun的网站上,我丢失了链接)。 现在,与多个/嵌套的if-else构造相比,这肯定会提升性能。

我的问题是,java如何在生成的字节码中实现基于访问者模式的Enums实现,与基于switch-case的实现相比,性能提升是什么?

我应该选择哪种类型的实现,考虑到我的Enums可能在未来增长,我也热衷于性能。 目前,我的Enum中有一些19和奇数常量。


编辑
我有一个类存储有关游戏变量的一些信息。 其中一个变量是Enum类型。

public class GameObject { private Shape mShape; public Shape getShape() { return mShape; } . . . public static enum Shape { SHAPE1, SHAPE2, SHAPE3, SHAPE4, ..., SHAPE20 }; public void drawShape() { switch (this.mShape) { case SHAPE1: drawShape1(); break; case SHAPE2: drawShape2(); break; case SHAPE3: drawShape3(); break; case SHAPE4: drawShape4(); break; . . . . . case SHAPE20: drawShape20(); break; default: drawUnknown(); break; } } 

}

后来我意识到将信息与逻辑分离,因此创建了另一个类并将Enum ShapeGameObject移动到这个新类GraphicModel ,而不是在那里使用switch-case ,我实现了特定于常量的方法 。 是的,在这次修改之后,我确实在任一类中输入了正确的import语句。

 public class GraphicModel { public void drawGraphicFromObject(GameObject gameObject) { gameObject.getShape().draw(); } public static enum Shape { // This method is not public, instead is only called by GraphicModel abstract void draw(); SHAPE1 { @Override void draw() { // some transformations } }, SHAPE2 { @Override void draw() { // Some different transformation } }, SHAPE3 { @Override void draw() { // Yet another transform } }, . . . . UNKNOWN { @Override void draw() { // } }; } } 

后来我甚至根据这里建议的访客模式实现了这个

那么,我需要知道的是哪种实施方式更有效? 当然,要在编译时将switch-case转换为跳转表 ,java需要在同一编译单元中使用枚举声明和switch语句。 我应该在我的GraphicModel类中使用基于开关的实现还是常量特定的方法实现? 相反,要清楚,性能有何不同?

一般来说,枚举在性能上与int常量相当,如果在switch语句中使用( 1 )。

也许您应该考虑一些常量特定方法实现的内容 ? 例如

 public enum Mode { ON { Color color() {return Color.GREEN;}}, OFF { Color color() {return Color.RED;}}, STANDBY { Color color() {return Color.YELLOW;}}, DEFAULT { Color color() {return Color.BLACK;}}; abstract Color color(); }//enum Mode 

然后使用

 getMode().color(); 

而不是一个开关声明?!

但是,我认为对于“仅获得颜色的情况”,可能根本不需要任何方法。

一般来说,我强烈建议您为书架使用Effective Java 。 第6章将讨论Enums和Annotations