在 Java 中是否应该始终使用枚举而不是常量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/367104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should you always use enums instead of constants in Java
提问by Draemon
In java <1.5, constants would be implemented like this
在 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;
}
...
and you would use it like this:
你会像这样使用它:
MyClass myClass = new MyClass(MyClass.VERTICAL);
Now, in 1.5 obviously you should be using enums:
现在,在 1.5 中显然你应该使用枚举:
public class MyClass {
public static enum Orientation {
VERTICAL, HORIZONTAL;
}
private Orientation orientation;
public MyClass(Orientation orientation) {
this.orientation = orientation;
}
...
and now you would use it like this:
现在你会像这样使用它:
MyClass myClass = new MyClass(MyClass.Orientation.VERTICAL);
Which I find slightly ugly. Now I could easily add a couple of static variables:
我觉得有点难看。现在我可以轻松添加几个静态变量:
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;
}
...
And now I can do this again:
现在我可以再次这样做:
MyClass myClass = new MyClass(MyClass.VERTICAL);
With all the type-safe goodness of enums.
具有枚举的所有类型安全优点。
Is this good style, bad style or neither. Can you think of a better solution?
这是好的风格,坏的风格还是两者都不是。你能想到更好的解决方案吗?
Update
更新
Vilx- was the first one to highlight what I feel I was missing - that the enum should be a first-class citizen. In java this means it gets its own file in the package - we don't have namespaces. I had thought this would be a bit heavyweight, but having actually done it, it definitely feels right.
Vilx - 是第一个强调我觉得我缺少的东西 - 枚举应该是一等公民。在 Java 中,这意味着它在包中拥有自己的文件——我们没有命名空间。我原以为这会有点重量级,但实际完成后,感觉绝对正确。
Yuval's answer is fine, but it didn't really emphasise the non-nested enum. Also, as for 1.4 - there are plenty of places in the JDK that use integers, and I was really looking for a way to evolve that sort of code.
Yuval 的回答很好,但它并没有真正强调非嵌套枚举。另外,至于 1.4 - JDK 中有很多地方使用整数,我真的在寻找一种方法来改进这种代码。
采纳答案by Vilx-
Don't know about Java, but in .NET the good practice is to put enums in parallel to the class that uses them, even if it is used by one class alone. That is, you would write:
不了解 Java,但在 .NET 中,好的做法是将枚举与使用它们的类并行放置,即使它被一个类单独使用。也就是说,你会写:
namespace Whatever
{
enum MyEnum
{
}
class MyClass
{
}
}
Thus, you can use:
因此,您可以使用:
MyClass c = new MyClass(MyEnum.MyValue);
回答by Yuval Adam
You complicated it too much. Let's bring it all together.
你太复杂了。让我们把它放在一起。
Post Java 1.5 you should use the Java Enum class:
在 Java 1.5 之后,您应该使用 Java Enum 类:
public enum Color
{
BLACK, WHITE;
}
Pre Java 1.5 you should use the type-safe Enum pattern:
在 Java 1.5 之前,您应该使用类型安全的 Enum 模式:
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;
}
}
In both ways you call it like so:
在这两种方式中,你都这样称呼它:
drawBackground(Color.WHITE);
Specifically, regarding your question. It's a matter of code style, but I think the preferred way is to keep enums in their separate classes. Especially once they start to get their own methods like getName(), getId(), etc... Think of it as the same dilemma as regular class vs. anonymous class, once the class starts to get cluttered, it's time to move it out to its own file.
具体来说,关于你的问题。这是代码风格的问题,但我认为首选的方法是将枚举保留在单独的类中。尤其是一旦他们开始获得自己的方法,例如getName(),getId()等... 将其视为与常规类与匿名类相同的困境,一旦类开始变得混乱,就该将其移到自己的文件中。
回答by Yoni Roit
Did you know you can import Orientation and say
您知道吗,您可以导入 Orientation 并说
MyClass myClass = new MyClass(Orientation.VERTICAL);
?
?
回答by Nate Parsons
It depends on how many values the enum can take. In your example, with only two, I would just use a boolean. If the enum will only be used by code that you write and won't have to interact with lots of other code, maybe you don't need type safety. But if it's in a 'public' method, I would definitely go for enums, and put the enum in its own file.
这取决于枚举可以采用多少个值。在你的例子中,只有两个,我只会使用一个布尔值。如果枚举仅由您编写的代码使用并且不必与许多其他代码交互,那么您可能不需要类型安全。但是如果它在一个“公共”方法中,我肯定会去枚举,并将枚举放在它自己的文件中。
回答by eulerfx
You can also have two static methods on MyClass:
您还可以在 MyClass 上使用两个静态方法:
MyClass.Vertical() : MyClass
MyClass.Horizontal() : MyClass
Those will return a new instance with proper enum set.
这些将返回一个具有适当枚举集的新实例。
回答by Kevin Le - Khnle
I agree you were creative but I think it's not a practical solution and I think you just shifted the "ugliness" to a different part of the code. What happens if in addition to VERTICAL and HORIZONTAL, you'll also have DIAGONAL, AA, BB, CC, etc? Are you going to have to duplicate by typing each and every static constant? Your taste that MyClass.Orientation.VERTICAL is ugly might be personal?
我同意你很有创意,但我认为这不是一个实用的解决方案,我认为你只是将“丑陋”转移到了代码的不同部分。如果除了 VERTICAL 和 HORIZONTAL 之外,还有对角线、AA、BB、CC 等,会发生什么情况?您是否必须通过键入每个静态常量来进行复制?您认为 MyClass.Orientation.VERTICAL 丑陋的品味可能是个人原因?
回答by Raedwald
There is an important class of cases where you should use constants instead of enums. This is when you want to do arithmetic using the constants, or compare them with numeric values. Then you really need the thing to be an int, longor double.
有一类重要的情况,您应该使用常量而不是enums。这是当您想使用常量进行算术运算或将它们与数值进行比较时。那么你真的需要这个东西是一个int,long或double。
Conversely, if it would never make sense to do arithmetic or numerical comparisons using a thing, that thing should be an object rather than a primitive numeric, so an enumwould be more appropriate.
相反,如果使用事物进行算术或数值比较永远没有意义,那么该事物应该是一个对象而不是原始数字,因此 anenum会更合适。

