79

列挙型の宣言に問題があります。私が作成しようとしているのは、3 つのダウンロード タイプ (AUDIO、VIDEO、AUDIO_AND_VIDEO) がある「DownloadType」の列挙型です。

次のようにコードを実装しました。

private enum DownloadType {
    AUDIO(0), VIDEO(1), AUDIO_AND_VIDEO(2);
    private final int value;

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

次のように使用すると、これは正常に機能します。

DownloadType.AUDIO_AND_VIDEO.value;

ただし、「値」を尋ねる必要がないようにしたいと思います。私は間違っているかもしれませんが、これは Font などの Java でいくつかのクラスが動作する方法です。たとえば、フォント スタイルを設定するには、次のようにします。

Font.PLAIN

これは int 値を返しますが、使用しません:

Font.PLAIN.value
4

8 に答える 8

108

Font.PLAINは列挙型ではありません。それはただintです。列挙型から値を取得する必要がある場合、列挙.value型は実際にはプリミティブではなく独自の型のオブジェクトであるため、メソッドの呼び出しまたは の使用を避けることはできません。

本当に のみが必要であり、int安全性が失われることをすでに受け入れている場合、ユーザーは無効な値を API に渡す可能性があります。これらの定数を次のように定義することもできintます。

public final class DownloadType {
    public static final int AUDIO = 0;
    public static final int VIDEO = 1;
    public static final int AUDIO_AND_VIDEO = 2;

    // If you have only static members and want to simulate a static
    // class in Java, then you can make the constructor private.
    private DownloadType() {}
}

ちなみに、メソッドvalueもあるため、フィールドは実際には冗長なので.ordinal()、次のように定義できますenum

enum DownloadType { AUDIO, VIDEO, AUDIO_AND_VIDEO }

を使用して「値」を取得します

DownloadType.AUDIO_AND_VIDEO.ordinal()

編集:コードを修正しました..Javastatic classでは許可されていません。Java で静的クラスを定義する方法の説明と詳細については、この SO の回答を参照してください。

于 2012-12-09T21:39:52.027 に答える
61

int 値を取得する必要がある場合は、ENUM に値のゲッターを用意してください。

private enum DownloadType {
    AUDIO(1), VIDEO(2), AUDIO_AND_VIDEO(3);
    private final int value;

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

    public int getValue() {
        return value;
    }
}

public static void main(String[] args) {
    System.out.println(DownloadType.AUDIO.getValue());           //returns 1
    System.out.println(DownloadType.VIDEO.getValue());           //returns 2
    System.out.println(DownloadType.AUDIO_AND_VIDEO.getValue()); //returns 3
}

ordinal()または、列挙型定数の列挙型定数の位置を返すメソッドを単純に使用することもできます。

private enum DownloadType {
    AUDIO(0), VIDEO(1), AUDIO_AND_VIDEO(2);
    //rest of the code
}

System.out.println(DownloadType.AUDIO.ordinal());            //returns 0
System.out.println(DownloadType.VIDEO.ordinal());            //returns 1
System.out.println(DownloadType.AUDIO_AND_VIDEO.ordinal()); //returns 2
于 2012-12-09T21:39:03.370 に答える
17

まず、次の質問を自問する必要があります: 本当に int が必要ですか?

列挙型の目的は、外部値 (int など) に依存することなく、コード内で意味を持つアイテム (定数) のコレクションを持つことです。Java の列挙型は、switch ステートメントの引数として使用でき、"==" 等値演算子 (とりわけ) を使用して安全に比較できます。

提案1(intは不要):

多くの場合、後ろに整数は必要ないので、単純にこれを使用します:

private enum DownloadType{
    AUDIO, VIDEO, AUDIO_AND_VIDEO
}

使用法:

DownloadType downloadType = MyObj.getDownloadType();
if (downloadType == DownloadType.AUDIO) {
    //...
}
//or
switch (downloadType) {
  case AUDIO:  //...
          break;
  case VIDEO: //...
          break;
  case AUDIO_AND_VIDEO: //...
          break;
}

提案 2 (int が必要) :

それでも、enum を int に変換すると便利な場合があります (たとえば、外部 API が int 値を想定している場合)。toXxx()この場合、 -Styleを使用してメソッドを変換メソッドとしてマークすることをお勧めします。オーバーライドの印刷用toString()

private enum DownloadType {
    AUDIO(2), VIDEO(5), AUDIO_AND_VIDEO(11);
    private final int code;

    private DownloadType(int code) {
        this.code = code;
    }

    public int toInt() {
        return code;
    }

    public String toString() {
        //only override toString, if the returned value has a meaning for the
        //human viewing this value 
        return String.valueOf(code);
    }
}

System.out.println(DownloadType.AUDIO.toInt());           //returns 2
System.out.println(DownloadType.AUDIO);                   //returns 2 via `toString/code`
System.out.println(DownloadType.AUDIO.ordinal());         //returns 0
System.out.println(DownloadType.AUDIO.name());            //returns AUDIO
System.out.println(DownloadType.VIDEO.toInt());           //returns 5
System.out.println(DownloadType.VIDEO.ordinal());         //returns 1
System.out.println(DownloadType.AUDIO_AND_VIDEO.toInt()); //returns 11

概要

  • 必要がない場合は、整数を列挙型と一緒に使用しないでください。
  • ordinal()列挙型の整数を取得するために using に依存しないでください。順序を変更すると (値を挿入するなどして)、この値が変わる可能性があるためです。使用を検討している場合は、ordinal()提案 1 を使用することをお勧めします。
  • タイプセーフが失われるため、通常は列挙型の代わりにint定数を使用しないでください(受け入れられた回答のように)。
于 2014-03-12T11:39:41.900 に答える
10

ordinal()列挙値でメソッドを呼び出すだけで、対応する番号を取得できます。追加属性をその値で宣言する必要はありません。列挙された各値はデフォルトで独自の番号を取得し、ゼロから始まり、宣言された順序で値ごとに 1 ずつ増加して割り当てられます。

intの値に依存するべきではなくenum、実際の値だけに依存すべきです。Java の列挙型は別の種類のモンスターであり、整数コードに依存する C の列挙型とは異なります。

質問で提供した例に関しては、Font.PLAINそれは Font クラスの単なる整数定数であるため機能します。(おそらく変更する)数値コードがどうしても必要な場合は、enum数値定数に固執することをお勧めします。

于 2012-12-09T21:40:33.213 に答える
5

このコードを試すことができます。

private enum DownloadType {
    AUDIO , VIDEO , AUDIO_AND_VIDEO ;

}

この列挙は次のように使用できますDownloadType.AUDIO.ordinal()。このコード スニペットがお役に立てば幸いです。

于 2014-11-23T10:24:18.400 に答える
3

列挙型を文字列と連結している場合は、toStringメソッドをオーバーライドしてintを返すことができます。

public String toString() {
    return value + "";
}

次に、単純に次を使用できます。

String something = "foo" + DownloadType.AUDIO;

toString()メソッドが呼び出されます。


プログラムでtoString()を使用することは、一般的に不適切な方法と見なされていることに注意してください。これは人間の目のみを対象としていますが、これが目的を達成する唯一の方法です。

于 2012-12-09T21:48:03.270 に答える