Как преобразовать значение enum в int?


240

У меня есть функция, которая возвращает тип int. Однако у меня есть только значение перечисления TAX.

Как я могу привести значение перечисления TAX к int?

public enum TAX {
    NOTAX(0),SALESTAX(10),IMPORTEDTAX(5);

    private int value;
    private TAX(int value){
        this.value = value;
    }
}

TAX var = TAX.NOTAX; // This value will differ

public int getTaxValue()
{
  // what do do here?
  // return (int)var;
}

1
Возможный дубликат Как сопоставить int и enum
— малат

Ответы:


354

Вам нужно было бы как- valueнибудь выставить enum , например

public enum Tax {
    NONE(0), SALES(10), IMPORT(5);

    private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

...

public int getTaxValue() {
    Tax tax = Tax.NONE; // Or whatever
    return tax.getValue();
}

(Кстати, я изменил названия, чтобы они стали более привычными и удобочитаемыми.)

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


1
@likejiujitsu: Это происходит в противоположном направлении. В этом вопросе OP уже имеет значение типа Taxи хочет получить из него числовое значение.
— Джон Скит

Я только что попробовал это и понял, что это терпит неудачу, myEnumValue = MyEnum.valueOf(myInt);arg должен иметь тип String - или я что-то упускаю?
— Likejudo

Это решение хуже, чем ничего. Кажется, перечисления в Java просто не должны использоваться? Или JDK 1.8 изменил это?
— ebyrob

@ebyrob: Учитывая голосование, кажется, что многие люди не согласны с вами, как и я. Если вам нужен фиксированный набор значений, перечисления вполне подойдут.
— Джон Скит

209

Я предпочитаю это:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

затем:

//cast enum to int
int color = Color.Blue.ordinal();

34
Это неверно / не рекомендуется Джошуа Блохом в его книге «Эффективная Java» (2-е изд). См. Пункт 31.
— user504342

43
@ user504342 У меня нет 2-го издания книги, поэтому не могли бы вы объяснить, почему это не рекомендуется?
— Likejudo

17
2 причины: во-первых, любая связь между порядковыми значениями и константами прекратится, если будут добавлены новые константы, и два документа API специально рекомендуют это.
— jordanpg

8
Так чисто и идеально. Я вижу несколько "не делай этого" и "не рекомендуется". Мне придется выяснить, почему это считается плохим. Некоторые раздутые образцы выглядят плохо IMO. Так много работы, чтобы сделать такую ​​простую задачу.
— Херб Михан

4
В команде вы уверены, что ваш со-разработчик добавит значение в середине (хуже в начале) или просто отсортирует их, потому что им нечего делать, и полностью испортит код, используя.ordinal()
— Майкл Лаффарг,

18

Если вы хотите, чтобы значение, которое вы назначаете в конструкторе, вам нужно добавить метод в определение enum, чтобы вернуть это значение.

Если вам нужен уникальный номер, представляющий значение перечисления, вы можете использовать ordinal().


2
Быть осторожен. Существует гораздо больше анти-паттернов развития, на которые опираются, ordinal()чем действительные варианты использования ordinal(). Если вам нужно сохранить уникальное значение для enum, то просто сохраните enum. Существуют EnumSets, Списки Enum, EnumMaps и почти любая другая коллекция Enum, которую вы можете захотеть получить.
— Эдвин Бак

1
@ EdwinBuck: Хорошо отметить, я просто хотел упомянуть о существовании, ordinal()потому что ОП не давал понять, что он хочет, чтобы int был на самом деле.
— unholysampler

Не получайте порядковый номер. Пожалуйста, проверьте enum api относительно этого. Голосование убрано.
— Полное судно на воздушной подушке

3
Интересно, что думают люди об использовании ordinal()внутри самого перечисления? Например, у меня есть перечисление под названием « Season» , который содержит значение Spring, Summer, Autumnи Winter, и это не публичный метод называется next()возвращающим values()[(ordinal() + 1) % 4] Наружно, не код когда - нибудь увидит порядковый номер, и никогда не будут дополнительные членами в этом перечислении, так что это похоже на действительный вариант использования.
— Даррел Хоффман

1
@DarrelHoffman У меня такое ощущение, что делать это хорошо, поскольку единственные веские аргументы, которые я вижу против использования ordinal()шарнира в далеко идущем коде, нарушаются из-за изменений в константах перечисления. Если вы собираетесь изменить константы перечисления, вы уже должны быть в этом файле. Большинство перечислений довольно короткие, и если это не так, вы все равно должны проверить файл более тщательно. В обоих случаях у вас, вероятно, next()все равно должен быть модульный тест, охватывающий ваш метод.
— Алан Хенсли

12

Иногда какой-то подход C # облегчает жизнь в мире Java ..:

class XLINK {
static final short PAYLOAD = 102, ACK = 103, PAYLOAD_AND_ACK = 104;
}
//Now is trivial to use it like a C# enum:
int rcv = XLINK.ACK;

Для меня это самый желательный путь. Я получаю преимущества enum (ясности кода), типа данных, который удобен для БД, и мне не нужно исследовать 100 альтернатив enum, чтобы сделать это «способом Android». Просто и эффективно.
— Джон Уорд

Ницца. Как будто java-перечисление просто совершенно не связано с реальностью того, для чего используется перечисление ... особенно, если люди тогда начинают злоупотреблять им для таких вещей, как одиночные игры. Этот подход имеет тот недостаток, что у него нет простого способа получить все значения.
— Нергудс

Разве у этого нет недостатка в попытке передать значение enum методу? Вы больше не можете передавать XLINK методу, потому что он не представляет ничего конкретного. Вы теряете ввод в свой метод. Подпись метода должна быть короткой, а не XLINK.
— Дастин Дженсен

2

Возможно, лучше использовать представление String, чем целое число, потому что String все еще действителен, если значения добавляются в перечисление. Вы можете использовать метод enum name () для преобразования значения перечисления в строку и метод перечисления valueOf () для повторного создания представления перечисления из строки. В следующем примере показано, как преобразовать значение перечисления в String и обратно (ValueType является перечислением):

ValueType expected = ValueType.FLOAT;
String value = expected.name();

System.out.println("Name value: " + value);

ValueType actual = ValueType.valueOf(value);

if(expected.equals(actual)) System.out.println("Values are equal");

1
public enum Tax {

NONE(1), SALES(2), IMPORT(3);

private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public String toString() {
        return Integer.toString(value);
    }
}

class Test {
    System.out.println(Tax.NONE);    //Just an example.
}

0

Несколько иной подход (по крайней мере, для Android) заключается в использовании аннотации IntDef для объединения набора констант int

@IntDef({NOTAX, SALESTAX, IMPORTEDTAX})
@interface TAX {}
int NOTAX = 0;
int SALESTAX = 10;
int IMPORTEDTAX = 5;

Использовать в качестве параметра функции:

void computeTax(@TAX int taxPercentage){...} 

или в объявлении переменной:

@TAX int currentTax = IMPORTEDTAX;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.