你应该总是使用枚举而不是Java中的常量

时间:2008-12-14 22:44:44

标签: java coding-style enums

在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);

具有所有类型安全的枚举功能。

这是好风格,坏风格还是两种风格。你能想到一个更好的解决方案吗?

更新

Vilx-是第一个突出我觉得我缺少的东西 - 这个enum应该是一流的公民。在java中,这意味着它在包中获得了自己的文件 - 我们没有名称空间。我曾经以为这会有点重量级,但实际上已经做到了,它绝对是正确的。

Yuval的答案很好,但它并没有真正强调非嵌套枚举。此外,对于1.4 - JDK中有很多使用整数的地方,我真的在寻找一种方法来发展这种代码。

7 个答案:

答案 0 :(得分:28)

你太复杂了。让我们把它们放在一起。

Post 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()等...将其视为与普通班级与匿名班级相同的困境,一旦班级开始变得混乱,它就是是时候将它移到自己的文件中了。

答案 1 :(得分:5)

您知道可以导入Orientation并说

MyClass myClass = new MyClass(Orientation.VERTICAL);

答案 2 :(得分:2)

不了解Java,但在.NET中,良好的做法是将枚举与使用它们的类并行放置,即使它仅由一个类使用。也就是说,你会写:

namespace Whatever
{
    enum MyEnum
    {
    }
    class MyClass
    {
    }
}

因此,您可以使用:

MyClass c = new MyClass(MyEnum.MyValue);

答案 3 :(得分:0)

这取决于枚举可以采用多少个值。在你的例子中,只有两个,我只会使用一个布尔值。如果枚举只能由您编写的代码使用,而不必与许多其他代码进行交互,那么您可能不需要类型安全。但如果它采用“公共”方法,我肯定会选择枚举,并将枚举放在自己的文件中。

答案 4 :(得分:0)

你也可以在MyClass上有两个静态方法:

MyClass.Vertical() : MyClass
MyClass.Horizontal() : MyClass

那些将返回一个具有适当枚举设置的新实例。

答案 5 :(得分:0)

我同意你很有创意,但我认为这不是一个实用的解决方案,我认为你只是将“丑陋”转移到了代码的不同部分。如果除了VERTICAL和HORIZONTAL之外,你还会有DIAGONAL,AA,BB,CC等?您是否需要通过键入每个静态常量来复制?你对MyClass.Orientation.VERTICAL丑陋的品味可能是个人的吗?

答案 6 :(得分:0)

有一类重要的案例,您应该使用常量而不是enum s。这是您想要使用常量进行算术运算,或者将它们与数值进行比较。那么你真的需要这个东西是intlongdouble

相反,如果使用一个东西进行算术或数值比较是没有意义的,那么该东西应该是一个对象而不是一个原始数字,所以enum更合适。