Если вы всегда используете перечисления вместо констант в 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);

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

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

Обновить

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

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

14.12.2008 22:44:44
В первом блоке кода вы хотели дать каждой переменной различное значение, верно?
Nate Parsons 14.12.2008 22:55:49
Вам на самом деле нужен класс MyClass, чтобы делать больше, чем могли бы делать разные ориентации?
Pål GD 14.12.2008 22:57:38
7 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

MyClass c = new MyClass(MyEnum.MyValue);
2
14.12.2008 22:52:40

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

MyClass myClass = new MyClass(Orientation.VERTICAL);

?

5
14.12.2008 22:47:55
Хорошая точка зрения. Да, я сделал, но это все еще означает больше многословия в вызывающем коде (это добавляет строку импорта). Моя мотивация - сделать код вызова короче и чище.
Draemon 14.12.2008 22:51:42
Я извиняюсь, чувак. Я имею в виду, я люблю Java и все такое , но короче никогда не было приоритетом в этом языке.
Yoni Roit 14.12.2008 22:55:25
Более короткие? Что за ... так что вместо одной строки импорта вы предпочитаете писать MyClass снова и снова? Это не короче и не чище для меня.
arul 14.12.2008 23:03:34

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

0
14.12.2008 22:59:34
У вас есть точка зрения, но использование enum немного более самоописательно, чем просто логическое значение.
Yoni Roit 14.12.2008 23:02:40
но если вы просто передаете его в функцию, тогда вы можете сделать подпись 'public MyClass (boolean isVertical)'. Хотя это единственный случай, которым я бы воспользовался.
Nate Parsons 15.12.2008 02:04:38

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

После 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()и т. Д. ... Думайте об этом как о той же самой дилемме, что и у обычного класса против анонимного класса, как только класс начинает загромождаться, пришло время перенести его в свой собственный файл.

27
2.07.2015 11:48:59

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

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

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

0
14.12.2008 23:03:18

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

0
14.12.2008 23:03:36
Я согласен, что я только что изменил уродство, но я всегда немного предпочитаю, чтобы оно было в вызываемом коде, а не в вызывающем коде. Это абсолютно личное, и я даже не уверен, что мне нравится альтернатива, поэтому я спрашиваю о перспективах. Я прихожу к выводу, что отдельный класс будет лучше.
Draemon 14.12.2008 23:10:17

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

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

0
2.07.2014 07:07:12