Java枚举return Int


76

我在声明枚举时遇到麻烦。我要创建的是“ 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

1
您也可以简单地使用DownloadType.AUDIO_AND_VIDEO,除非您需要价值,否则我会缺少什么吗?
科萨2012年

@Nambari如果我是System.out.println(DownloadType.AUDIO_AND_VIDEO),则返回“ AUDIO_AND_VIDEO”,该类型显然是“ DownloadType”类型,而不是int类型。
克里斯蒂安

3
我认为您在混淆枚举的目的。为什么还需要整数?
Jivings

因为我在考虑是否要获取该类型,所以可以使用'if(downloadType == DownloadType.AUDIO){}',这样对吗?
克里斯蒂安

1
toString()当您打印对象时,将调用该方法。同样,PLAINFont类中的常量,而不是枚举。
Andrew Logvinov

Answers:


102

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()方法,因此可以将enumas定义为:

enum DownloadType { AUDIO, VIDEO, AUDIO_AND_VIDEO }

并使用

DownloadType.AUDIO_AND_VIDEO.ordinal()

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


感谢您的澄清,现在这很有意义。与创建枚举不同,我将创建一个公共DownloadType {private static final int AUDIO = 0; 这应该是InnerClass吗?感谢您的回答。
克里斯蒂安

@克里斯蒂安:这主要取决于您要如何访问它。
kennytm

感谢您的回答,正是我想要的-等待3分钟才能接受
Cristian

你是说吗public static final int AUDIO = 0;?据我了解,const这不是有效的Java关键字。
本杰明·

2
顺序可能会导致系统
不稳定-hychou

59

如果需要获取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

3
当您可以简单地调用.value并且已经提供了一种方法ordinal()来获取整数时,为什么需要额外的方法。
科萨2012年

@Nambari umm,不是知道枚举具有序数..我多么愚蠢:P
PermGenError 2012年

@GanGnaMStYleOverFlowErroR感谢您的回答,但是我实际上是在避免调用.value,更不用说创建另一个方法并调用getValue()了:)
Cristian

@GanGnaMStYleOverFlowErroR:是的,我可以在评论中澄清这一点。
科萨2012年

@Nambari没有问题,谢谢您让我知道ordinal():)
PermGenError 2012年

16

首先,您应该问自己以下问题:您真的需要一个int吗?

枚举的目的是拥有一个项目(常量)的集合,这些项目在代码中具有含义,而无需依赖于外部值(例如int)。Java中的枚举可以用作切换语句的参数,并且可以使用“ ==”等号运算符(除其他外)安全地进行比较。

提案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

概要

  • 如果不需要,请不要将Integer与枚举一起使用。
  • 不要依赖于使用ordinal()来获取枚举的整数,因为如果更改顺序(例如,通过插入值),则此值可能会更改。如果您正在考虑ordinal()使用建议1,则可能会更好。
  • 通常不要使用int常量而不是枚举(例如在接受的答案中),因为您将失去类型安全性。

+1指向toString()虽然INT就成了一个字符串,我不打算使用它,因为那:)的
安东尼奥·阿尔梅达

...然后使用ordinal()。但toInt()我认为更好
yonojoy,

10

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

你不应该依赖于int的价值enum,只有在其实际价值。Java中的枚举是另一种怪兽,与C中的枚举不同,在C中,枚举取决于它们的整数代码。

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


1
我知道ordinal(),但是如果我以后想更改或指定其他顺序,则会导致问题。我想指定int值
Cristian

1
@Cristian,您不应仅依赖于枚举的int值,而应取决于其实际值。Java中的枚举与C中的枚举不同,在C中,枚举取决于它们的整数代码。
奥斯卡·洛佩斯

@Cristian并针对您在问题中提供的示例Font.PLAIN起作用,因为这只是Font该类的整数常量。如果您绝对需要一个(可能会更改的)数字代码,那么anenum并不是工作的正确工具,最好坚持使用数字常量。
奥斯卡·洛佩斯

5

您可以尝试使用此代码。

private enum DownloadType {
    AUDIO , VIDEO , AUDIO_AND_VIDEO ;

}

您可以使用此枚举是这样的:DownloadType.AUDIO.ordinal()。希望此代码段对您有所帮助。


3

如果将枚举与字符串连接,则可以重写toString方法以返回int:

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

然后,您可以简单地使用:

String something = "foo" + DownloadType.AUDIO;

和toString()方法将被调用。


请注意,以编程方式使用toString()通常被认为是较差的做法-仅适用于人眼,但这是实现您所要求的唯一方法。


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());
}

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();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.