我一直在寻找几天来找到这个基于效果的问题的答案 到目前为止,在挖掘了Internet之后,我了解到有几种方法可以在java中使用Enums,这在here中有详细记载。 好吧,作为初学者,我希望在 switch-case 语句中使用Enums,这样可以提供清晰度并更好地理解代码。但另一方面,我们还有一个访问者模式样式的Enums实现,它确保了类型的安全性和可扩展性,讨论here。
话虽如此,并回到这个问题背后的原始想法,到目前为止,我已经了解到如果使用Enums正确设计switch-case结构,这确保了案例值不稀疏,并且Enum声明是在与switch-case语句相同的编译单元中,java编译器通过实现跳转表这样的构造对生成的字节码执行一些优化(在here和其他地方讨论过)在Sun的网站上,我丢失了链接)。现在,与多个/嵌套的if-else构造相比,这肯定会提升性能。
我的问题是,java如何在生成的字节码中实现基于访问者模式的Enums实现,与基于 switch-case 的实现(如果有)相比,性能提升了多少? / p>
我应该选择哪种类型的实现,考虑到我的枚举可能在将来增长,我也热衷于性能。目前,我的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;
}
}
}
后来我意识到将信息与逻辑分离,因此创建了另一个类,并从 GameObject <移动 Enum Shape / strong>到这个新类 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() {
//
}
};
}
}
后来我甚至按照建议here
基于访客模式实现了这一点那么,我需要知道的是哪种实施方式更有效?当然,要在编译时将 switch-case 转换为跳转表,java需要 enum 声明和开关同一编译单元中的语句。 我应该在 GraphicModel 类中使用基于 switch 的实现或常量特定方法实现吗? 相反,要明确,性能有何不同?
答案 0 :(得分:4)
一般来说,如果在 switch 语句(1)中使用,则枚举的性能与 int 常量相当。
也许您应该考虑常量特定方法实现的内容? e.g。
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 。