79

我在声明枚举时遇到了麻烦。我要创建的是“DownloadType”的枚举,其中有 3 种下载类型(AUDIO、VIDEO、AUDIO_AND_VIDEO)。

我已经实现了如下代码:

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;

但是,我希望这样我就不必要求“价值”。我可能弄错了,但这是几个类在 Java 中的工作方式,例如 Font,例如要设置字体样式,您可以使用:

Font.PLAIN

它返回一个 int 值,我们不使用:

Font.PLAIN.value
4

8 回答 8

108

Font.PLAIN不是枚举。它只是一个int. 如果您需要从枚举中取出值,则无法避免调用方法或使用 a .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()

编辑:更正了代码..static class在Java中是不允许的。请参阅此 SO 答案,其中包含有关如何在 Java 中定义静态类的说明和详细信息。

于 2012-12-09T21:39:52.027 回答
61

如果您需要获取 int 值,只需为您的 ENUM 中的值设置一个 getter:

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

然而,有时将枚举转换为 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()获取枚举的整数,因为如果您更改顺序(例如通过插入值),此值可能会更改。如果您正在考虑使用ordinal()它可能会更好地使用提案 1。
  • 通常不要使用 int 常量而不是枚举(如在接受的答案中),因为您将失去类型安全性。
于 2014-03-12T11:39:41.900 回答
10

只需ordinal()在枚举值上调用该方法,即可检索其对应的数字。没有必要用它的值声明一个附加属性,每个枚举值默认都有自己的数字,从零开始分配,每个值按照声明的顺序递增一。

您不应该依赖 a 的int值,而应该enum只依赖于它的实际值。Java 中的枚举是一种不同的怪物,它不像 C 中的枚举,您依赖于它们的整数代码。

关于您在问题中提供的示例,Font.PLAIN因为这只是 Font 类的整数常量。如果您绝对需要(可能会更改)数字代码,那么 anenum不是该工作的正确工具,最好坚持使用数字常量。

于 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 回答
3

你想要这个代码吗?

public static enum FieldIndex {
    HDB_TRX_ID,     //TRX ID
    HDB_SYS_ID      //SYSTEM ID
}

public String print(ArrayList<String> itemName){
    return itemName.get(FieldIndex.HDB_TRX_ID.ordinal());
}
于 2015-03-26T08:19:45.390 回答
2

在我看来,最易读的版本

public enum PIN_PULL_RESISTANCE {
    PULL_UP {
        @Override
        public int getValue() {
            return 1;
        }
    },
    PULL_DOWN {
        @Override
        public int getValue() {
            return 0;
        }
    };

    public abstract int getValue();
}
于 2020-02-23T09:49:39.803 回答