列挙値を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;
}

回答:


354

valueどういうわけか、列挙型を公開する必要があります。

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、そしてそこから数値を取得したいです。
Jon Skeet

私はちょうどそれを試してみて、それが失敗することに気づきましmyEnumValue = MyEnum.valueOf(myInt);たargはString型でなければなりません-あるいは何か足りないものはありますか?
likejudo 2014

この解決策は何もないより悪いです。Javaの列挙型は使用すべきではないようです?それともJDK 1.8はそれを変えましたか?
ebyrob 2016

@ebyrob:私のように、投票を考えると、多くの人があなたに反対しているようです。値の固定セットが必要な場合は、列挙型で十分です。
Jon Skeet、

209

私はこれが好きです:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

次に:

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

34
これは誤りであり、Joshua Blochの著書「Effective Java(2nd ed)」で推奨されていません。項目31.を参照してください
user504342

43
@ user504342本の第2版を持っていないので、推奨されない理由の要点を教えてください。
likejudo 2014

17
2つの理由:1つは、序数値と定数の間の関連付けは、新しい定数が追加された場合に解除されます。2つは、APIドキュメントで特に推奨されていません。
jordanpg 2014年

8
とても清潔で完璧です。「しないでください」と「非推奨」がいくつか表示されます。なぜそれが悪いと考えられているのかを調査する必要があります。肥大化したサンプルの一部はIMOの見た目が悪い。このような単純なタスクを実行するには、多くの作業が必要です。
ハーブミーハン

4
チームでは、共同開発者が真ん中に(最初は悪い)値を追加するか、何もせずにコードを完全に混乱させるために並べ替えるだけだと.ordinal()
確信し

18

コンストラクターで割り当てる値が必要な場合は、列挙型定義にメソッドを追加して、その値を返す必要があります。

列挙値を表す一意の数値が必要な場合は、を使用できますordinal()


2
注意してください。のordinal()有効な使用例よりも多くの開発アンチパターンに依存していordinal()ます。の一意の値を保存する必要がある場合はenum、を保存してくださいenum。EnumSets、Enumsのリスト、EnumMaps、および他のほぼすべてのEnumコレクションを利用可能にすることができます。
エドウィンバック

1
@EdwinBuck:それは指摘に値します。OP ordinal()がintを実際に何にしたいのか明確にしていないので、私はその存在について言及したいと思います。
unholysampler 2011年

序数を取得しないでください。これについては、enum apiを確認してください。賛成投票を削除しました。
ホバークラフトフルウナギ

3
ordinal()列挙自体の内部での使用についての人々の考えは何だろうと思います。たとえば、私は「と呼ばれる列挙持っていると言うSeason値が含まれている」SpringSummerAutumn、そしてWinter、それが呼び出されるパブリックメソッド持ちnext()返しvalues()[(ordinal() + 1) % 4] 、外部を、何のコードがこれまで序数を見ていないし、この列挙では、追加のメンバーがなることはありませんしたがって、有効なユースケースのようです。
Darrel Hoffman

1
@DarrelHoffman私の考えでは、それを行うのは問題ないと思います。なぜなら、ordinal()遠く離れたコードでヒンジを使用することに反対する唯一の強力な引数は、列挙型列挙定数の変更によって壊れているからです。列挙型の定数を変更する場合は、そのファイルにすでに存在している必要があります。ほとんどの列挙型はかなり短く、そうでない場合は、とにかくファイルを徹底的にチェックする必要があります。どちらの場合も、next()とにかくメソッドをカバーする単体テストが必要です。
Alan Hensley

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(コードの明快さ)、つまりDBに適したデータ型の利点が得られます。 "androidの方法"を行うために100のenumの代替案を調査する必要はありません。シンプルで効果的。
ジョンワード

いいね。それはまるで、Java enumがenumの用途の現実から完全に切り離されているかのようです...特に人々がシングルトンのようなもののためにそれを乱用し始めた場合は特にそうです。ただし、このアプローチには欠点がありますが、すべての値を取得する簡単な方法はありません。
Nyerguds、

これには、列挙値をメソッドに渡そうとするという欠点はありませんか?XLINKは具体的に何も表していないため、XLINKをメソッドに渡すことはできなくなりました。メソッドへの入力を失います。メソッドシグネチャは、XLINKの代わりに短く読み取る必要があります。
ダスティンジェンセン

2

列挙型に値が追加された場合でも文字列は有効であるため、整数よりも文字列表現を使用する方が良いでしょう。enumのname()メソッドを使用してenum値をStringに変換し、enumのvalueOf()メソッドを使用してStringからenum表現を再度作成できます。次の例は、enum値をStringに変換して戻す方法を示しています(ValueTypeはenumです)。

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;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.