你应该总是使用枚举而不是Java中的常量
在java <1.5中,常量将像这样实现
public class MyClass { public static int VERTICAL = 0; public static int HORIZONTAL = 1; private int orientation; public MyClass(int orientation) { this.orientation = orientation; } ...
你会像这样使用它:
MyClass myClass = new MyClass(MyClass.VERTICAL);
现在,在1.5中显然你应该使用枚举:
public class MyClass { public static enum Orientation { VERTICAL, HORIZONTAL; } private Orientation orientation; public MyClass(Orientation orientation) { this.orientation = orientation; } ...
现在你会像这样使用它:
MyClass myClass = new MyClass(MyClass.Orientation.VERTICAL);
我觉得有点难看。 现在我可以轻松添加几个静态变量:
public class MyClass { public static Orientation VERTICAL = Orientation.VERTICAL; public static Orientation HORIZONTAL = Orientation.HORIZONTAL; public static enum Orientation { VERTICAL, HORIZONTAL; } private Orientation orientation; public MyClass(Orientation orientation) { this.orientation = orientation; } ...
现在我可以再次这样做:
MyClass myClass = new MyClass(MyClass.VERTICAL);
具有所有类型安全的枚举function。
这是好风格,坏风格还是两种风格。 你能想到更好的解决方案吗?
更新
Vilx-是第一个突出我觉得我缺少的东西 – 枚举应该是一流的公民。 在java中,这意味着它在包中获得了自己的文件 – 我们没有名称空间。 我曾经以为这会有点重量级,但实际上已经做到了,它绝对是正确的。
Yuval的答案很好,但它并没有真正强调非嵌套枚举。 另外,对于1.4 – JDK中有很多使用整数的地方,我真的在寻找一种方法来改进这种代码。
不了解Java,但在.NET中,良好的做法是将枚举与使用它们的类并行放置,即使它仅由一个类使用。 也就是说,你会写:
namespace Whatever { enum MyEnum { } class MyClass { } }
因此,您可以使用:
MyClass c = new MyClass(MyEnum.MyValue);
你太复杂了。 让我们一起来吧。
在Java 1.5之后,你应该使用Java Enum类:
public enum Color { BLACK, WHITE; }
Pre Java 1.5你应该使用类型安全的枚举模式:
public class Color { public static Color WHITE = new Color("white"); public static Color BLACK = new Color("black"); private String color; private Color(String s) { color = s; } }
在这两种方式中,你都这样称呼它:
drawBackground(Color.WHITE);
具体来说,关于你的问题。 这是代码风格的问题,但我认为首选的方法是将枚举保存在各自的类中。 特别是一旦他们开始得到他们自己的方法,如getName()
, getId()
等…把它想象成与常规类和匿名类相同的困境,一旦类开始变得混乱,是时候移动它了出自己自己的文件。
你知道吗,你可以导入Orientation并说出来
MyClass myClass = new MyClass(Orientation.VERTICAL);
?
这取决于枚举可以采用多少个值。 在你的例子中,只有两个,我只会使用一个布尔值。 如果枚举只能由您编写的代码使用,而不必与许多其他代码交互,那么您可能不需要类型安全。 但如果它采用“公共”方法,我肯定会选择枚举,并将枚举放在自己的文件中。
你也可以在MyClass上有两个静态方法:
MyClass.Vertical() : MyClass MyClass.Horizontal() : MyClass
这些将返回具有适当枚举集的新实例。
我同意你很有创意,但我认为这不是一个实用的解决方案,我认为你只是将“丑陋”转移到了代码的不同部分。 如果除了VERTICAL和HORIZONTAL之外你还会有DIAGONAL,AA,BB,CC等会发生什么? 您是否需要通过键入每个静态常量来复制? 你对MyClass.Orientation.VERTICAL丑陋的品味可能是个人的吗?
有一类重要的情况应该使用常量而不是enum
。 这是您想要使用常量进行算术运算,或者将它们与数值进行比较。 那么你真的需要这个东西是int
, long
或double
。
相反,如果使用一个东西进行算术或数值比较是没有意义的,那么该东西应该是一个对象而不是一个原始数字,所以enum
更合适。