【问题标题】:Java Enum return IntJava 枚举返回 Int
【发布时间】:2012-11-27 08:16:09
【问题描述】:

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

【问题讨论】:

  • 除非你需要价值,否则你也可以简单地使用 DownloadType.AUDIO_AND_VIDEO,我错过了什么吗?
  • @Nambari If I System.out.println(DownloadType.AUDIO_AND_VIDEO) 它返回“AUDIO_AND_VIDEO”,这显然是“DownloadType”类型,而不是 int。
  • 我认为你混淆了枚举的目的。为什么还需要整数?
  • 因为我在想如果我想得到我可以使用的类型'if (downloadType == DownloadType.AUDIO){}',是不是不对?
  • 打印对象时会调用toString() 方法。此外,PLAINFont 类中的常量,而不是枚举。

标签: java enums


【解决方案1】:

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

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

【讨论】:

  • 感谢您的澄清,现在这很有意义。我不会创建一个枚举,而是创建一个 public DownloadType { private static final int AUDIO = 0; ... 这应该是一个 InnerClass 吗?谢谢你的回答。
  • @Cristian:主要看你想怎么访问。
  • 感谢您的回答,正是我想要的 - 等待 3 分钟接受
  • 你的意思是public static final int AUDIO = 0;。据我所知,const 不是有效的 Java 关键字。
  • 序数可能导致系统不稳定
【解决方案2】:

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

【讨论】:

  • 当您可以简单地调用 .value 并且已经提供了一个方法 ordinal() 来获取整数时,为什么还需要额外的方法。
  • @Nambari umm,你知道枚举有序数..我多么愚蠢:P
  • @GanGnaMStYleOverFlowErroR 感谢您的回答,但我实际上是想避免调用 .value,更不用说创建另一个方法并调用 getValue() :)
  • @GanGnaMStYleOverFlowErroR:没错,我本可以在评论中澄清这一点。
  • @Nambari no problomo,感谢您让我知道 ordinal() :)
【解决方案3】:

首先你应该问自己以下问题:你真的需要一个 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 常量代替枚举(就像在接受的答案中一样),因为您会失去类型安全性。

【讨论】:

  • +1 用于指向 toString(),尽管 int 变成了字符串,因此我不会使用它:)
【解决方案4】:

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

您不应依赖enumint 值,而应仅依赖其实际值。 Java 中的枚举是一种不同的怪物,它不像 C 中的枚举,你依赖于它们的整数代码。

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

【讨论】:

  • 我知道 ordinal(),但是如果我以后想更改或指定不同的顺序,这将导致问题。我想指定 int 值
  • @Cristian 您不应依赖枚举的 int 值,而应仅依赖其实际值。 Java 中的枚举与 C 中的枚举不同,C 中的枚举依赖于它们的整数代码。
  • @Cristian 并且关于您在问题Font.PLAIN 中提供的示例,因为这只是Font 类的整数常量。如果您绝对需要(可能会更改)数字代码,那么 enum 不是该工作的正确工具,最好坚持使用数字常量。
【解决方案5】:

你可以试试这个代码。

private enum DownloadType {
    AUDIO , VIDEO , AUDIO_AND_VIDEO ;

}

您可以像这样使用此枚举:DownloadType.AUDIO.ordinal()。希望此代码 sn-p 对您有所帮助。

【讨论】:

    【解决方案6】:

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

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

    那么你可以简单地使用:

    String something = "foo" + DownloadType.AUDIO;
    

    toString() 方法将被调用。


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

    【讨论】:

      【解决方案7】:

      你想要这段代码吗?

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

      【讨论】:

        【解决方案8】:

        我认为最易读的版本

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

        【讨论】:

          猜你喜欢
          • 2017-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-14
          • 2013-09-23
          • 2022-01-12
          • 2015-11-28
          • 2015-10-29
          相关资源
          最近更新 更多