Если вы всегда используете перечисления вместо констант в Java - PullRequest
12 голосов
/ 15 декабря 2008

В java <1.5 константы будут реализованы следующим образом </p>

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

Со всеми типобезопасными перечислениями.

Это хороший стиль, плохой стиль или нет. Можете ли вы придумать лучшее решение?

Update

Vilx - был первым, кто выдвинул на первый план то, что я чувствую, что я скучал - что enum должен быть первоклассным гражданином. В Java это означает, что он получает свой собственный файл в пакете - у нас нет пространств имен. Я думал, что это будет немного тяжеловесно, но на самом деле, это определенно кажется правильным.

Ответ Ювала хорош, но он не особо подчеркивал не вложенное перечисление. Кроме того, что касается 1.4 - в JDK есть много мест, где используются целые числа, и я действительно искал способ развить такой код.

Ответы [ 7 ]

28 голосов
/ 15 декабря 2008

Ты слишком много усложнил. Давайте свяжем все это вместе.

После Java 1.5 вы должны использовать класс Java Enum:

public enum Color
{
    BLACK, WHITE;
}

До 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;
    }
}

В обоих случаях вы называете это так:

drawBackground(Color.WHITE);

В частности, относительно вашего вопроса. Это вопрос стиля кода, но я думаю, что предпочтительнее хранить перечисления в отдельных классах. Особенно, когда они начинают получать свои собственные методы, такие как getName(), getId() и т. Д. ... Думайте об этом как о той же дилемме, что и обычный класс против анонимного класса, как только класс начинает загромождаться, пора его перемещать в свой собственный файл.

5 голосов
/ 15 декабря 2008

Знаете ли вы, что вы можете импортировать Ориентацию и сказать

MyClass myClass = new MyClass(Orientation.VERTICAL);

2 голосов
/ 15 декабря 2008

Не знаю о Java, но в .NET рекомендуется помещать перечисления параллельно классу, который их использует, даже если он используется одним классом. То есть вы бы написали:

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

Таким образом, вы можете использовать:

MyClass c = new MyClass(MyEnum.MyValue);
0 голосов
/ 02 июля 2014

Существует важный класс случаев, когда вы должны использовать константы вместо enum с. Это когда вы хотите сделать арифметику с использованием констант или сравнить их с числовыми значениями. Тогда вам действительно нужно, чтобы это было int, long или double.

И наоборот, если никогда не было бы смысла проводить арифметические или числовые сравнения с использованием какой-либо вещи, эта вещь должна быть объектом, а не примитивным числовым значением, поэтому enum будет более уместным.

0 голосов
/ 15 декабря 2008

Я согласен, что вы были креативны, но я думаю, что это не практичное решение, и я думаю, что вы просто перенесли «безобразие» в другую часть кода. Что произойдет, если в дополнение к VERTICAL и HORIZONTAL у вас также будут DIAGONAL, AA, BB, CC и т. Д.? Вы собираетесь дублировать, печатая каждую статическую константу? Твой вкус, что уродливое MyClass.Orientation.VERTICAL может быть личным?

0 голосов
/ 15 декабря 2008

Вы также можете использовать два статических метода в MyClass:

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

Они вернут новый экземпляр с правильным набором перечислений.

0 голосов
/ 15 декабря 2008

Это зависит от того, сколько значений может принимать перечисление. В вашем примере, только с двумя, я бы просто использовал логическое значение. Если enum будет использоваться только кодом, который вы пишете, и не будет взаимодействовать с большим количеством другого кода, возможно, вам не нужна безопасность типов. Но если это публичный метод, я бы определенно выбрал перечисления и поместил перечисление в отдельный файл.

...