【问题标题】:Java using enum with switch statementJava 使用带有 switch 语句的枚举
【发布时间】:2011-12-27 21:10:06
【问题描述】:

我查看了与此问题类似的 SO 上的各种问答,但没有找到解决方案。

我所拥有的是一个枚举,它代表查看电视指南的不同方式...

在 NDroid Application 类中

static enum guideView {
    GUIDE_VIEW_SEVEN_DAY,
    GUIDE_VIEW_NOW_SHOWING,
    GUIDE_VIEW_ALL_TIMESLOTS
}

...当用户更改视图时,事件处理程序会收到来自 0-2 的 int,我想做这样的事情...

在 Android Activity onClick(DialogInterface dialog, int which) 事件处理程序中

// 'which' is an int from 0-2
switch (which) {
    case NDroid.guideView.GUIDE_VIEW_SEVEN_DAY:
    ...
    break;
}

我已经习惯了 C# 枚举和 select/case 语句,它们允许像上面这样的事情,我知道 Java 做的事情不同,但我就是无法理解我需要做什么。

我将不得不诉诸if 声明吗?可能只有 3 个选择,所以我可以做到,但我想知道如何使用 Java 中的 switch-case 来完成。

编辑 抱歉,我没有完全扩展该问题,因为我将其视为一般 Java 问题。我已经添加到问题中以进一步解释。

没有任何特定于 Android 的东西,这就是为什么我没有将其标记为 Android,但枚举是在 Application 类中定义的,而我不想切换的代码在 Activity 中。枚举是静态的,因为我需要从多个活动中访问它。

【问题讨论】:

  • 正确导入后应该是case GUIDE_VIEW_SEVEN_DAY;你有什么问题?
  • 你不能让你的事件处理程序接收一个枚举吗?除此之外,也许这会有所帮助:stackoverflow.com/questions/5292790/…
  • @Dave:糟糕,抱歉,我已经更正了代码以显示它是怎样的。 Eclipse 给我一个类型不匹配的错误,说它不能从 guideView 转换为 int。
  • @Brian:这是一个 Android 应用程序,事件处理程序 (OnClickListener ) 由我必须实现的 DialogInterface 接口定义。
  • @MisterSquonk 哦,我想念你是从一个 int 中得到它的——对不起,请参阅 Ophidian 的回答,尽管我会将功能放在枚举中。

标签: java enums switch-statement


【解决方案1】:

您缺少的部分是将整数转换为类型安全的枚举。 Java 不会自动执行此操作。有几种方法可以解决这个问题:

  1. 使用静态最终 int 列表而不是类型安全的枚举并打开您收到的 int 值(这是 Java 5 之前的方法)
  2. 打开指定的 id 值(如described by heneryville)或枚举值的序数值;即guideView.GUIDE_VIEW_SEVEN_DAY.ordinal()
  3. 判断int值代表的枚举值,然后开启枚举值。

    enum GuideView {
        SEVEN_DAY,
        NOW_SHOWING,
        ALL_TIMESLOTS
    }
    
    // Working on the assumption that your int value is 
    // the ordinal value of the items in your enum
    public void onClick(DialogInterface dialog, int which) {
        // do your own bounds checking
        GuideView whichView = GuideView.values()[which];
        switch (whichView) {
            case SEVEN_DAY:
                ...
                break;
            case NOW_SHOWING:
                ...
                break;
        }
    }
    

    您可能会发现编写自定义 valueOf 实现更有用/更不容易出错,该实现将整数值作为参数来解析适当的枚举值并让您集中检查边界。

【讨论】:

  • 非常感谢。我花了一段时间才将它融入我的代码中,但现在它与您发布的示例代码一起工作得很好。 6 年的 C# 和 1 年的 Java - 我并不经常遇到让我难过的东西。有很多相似之处,但偶尔会有这样的,这是非常不同的。我不会很快忘记这个。 :-)
  • 你需要case语句中的非限定枚举名,所以case GuideView.SEVEN_DAY:给出编译错误,应该是case SEVEN_DAY:
【解决方案2】:

如果 whichView 是 GuideView 枚举的对象,则以下操作效果很好。请注意,case 之后的常量没有限定符。

switch (whichView) {
    case SEVEN_DAY:
        ...
        break;
    case NOW_SHOWING:
        ...
        break;
}

【讨论】:

    【解决方案3】:

    枚举不应像 NDroid.guideView.GUIDE_VIEW_SEVEN_DAY 那样在 case 标签中限定,而应删除限定条件并使用 GUIDE_VIEW_SEVEN_DAY

    【讨论】:

      【解决方案4】:

      我喜欢 Java 枚举的一些用法:

      1. .name() 允许您获取字符串中的枚举名称。
      2. .ordinal() 允许您获取整数值,从 0 开始。
      3. 您可以在每个枚举中附加其他值参数。
      4. 当然还有开关启用。

      带值参数的枚举:

          enum StateEnum {
              UNDEFINED_POLL  ( 1 * 1000L,       4 * 1000L),
              SUPPORT_POLL    ( 1 * 1000L,       5 * 1000L),
              FAST_POLL       ( 2 * 1000L,  4 * 60 * 1000L),
              NO_POLL         ( 1 * 1000L,       6 * 1000L); 
              ...
          }
      

      切换示例:

      private void queuePoll(StateEnum se) {
          // debug print se.name() if needed
          switch (se) {
              case UNDEFINED_POLL:
                  ...
                  break;
              case SUPPORT_POLL:
                  ...
                  break;
      

      【讨论】:

        【解决方案5】:

        这应该按照您描述的方式工作。你遇到了什么错误?如果您可以粘贴您的代码,那会有所帮助。

        http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

        编辑:您确定要定义静态枚举吗?这对我来说听起来不对。枚举与任何其他对象非常相似。如果您的代码编译并运行但给出不正确的结果,这可能就是原因。

        【讨论】:

        • “嵌套枚举类型是隐式静态的。允许将嵌套枚举类型显式声明为静态。”—JLS §8.9
        • @trashgod,确实-但我总是使用隐式声明来避免混淆,因为这实际上是更明显的 IMO。在大多数情况下,全局静态枚举(我认为是这样的)可能是错误的。
        【解决方案6】:

        短关联函数示例:

        public String getIcon(TipoNotificacao tipo)
        {
            switch (tipo){
                case Comentou : return "fa fa-comments";
                case ConviteEnviou : return "icon-envelope";
                case ConviteAceitou : return "fa fa-bolt";
                default: return "";
            }
        }
        

        就像@Dhanushka 所说,省略“switch”中的限定符是关键。

        【讨论】:

          【解决方案7】:
          enumerations accessing is very simple in switch case
          
          private TYPE currentView;
          
          //declaration of enum 
          public enum TYPE {
                  FIRST, SECOND, THIRD
              };
          
          //handling in switch case
          switch (getCurrentView())
                  {
                  case FIRST:
                      break;
                  case SECOND:
                      break;
                  case THIRD:
                      break;
                  }
          
          //getter and setter of the enum
          public void setCurrentView(TYPE currentView) {
                  this.currentView = currentView;
              }
          
              public TYPE getCurrentView() {
                  return currentView;
              }
          
          //usage of setting the enum 
          setCurrentView(TYPE.FIRST);
          
          avoid the accessing of TYPE.FIRST.ordinal() it is not recommended always
          

          【讨论】:

          • 只有在您没有从外部获取数据的情况下才有效。由于 OP 说 which 返回值 1, 2, 3 而不是 TYPE 你的方法将无法工作,如果没有一个反转的 switch case 需要 1, 2, 3 并在进入他列出的 switch case 之前返回一个 TYPE ..
          【解决方案8】:

          我就是这样做的

          public enum State
          {
              // Retrieving, // the MediaRetriever is retrieving music //
              Stopped, // media player is stopped and not prepared to play
              Preparing, // media player is preparing...
              Playing, // playback active (media player ready!). (but the media player
                          // may actually be
                          // paused in this state if we don't have audio focus. But we
                          // stay in this state
                          // so that we know we have to resume playback once we get
                          // focus back)
              Paused; // playback paused (media player ready!)
          
              //public final static State[] vals = State.values();//copy the values(), calling values() clones the array
          
          };
          
          public State getState()
          {
                  return mState;   
          }
          

          并在 Switch 语句中使用

          switch (mService.getState())
          {
          case Stopped:
          case Paused:
          
              playPause.setBackgroundResource(R.drawable.selplay);
              break;
          
          case Preparing:
          case Playing:
          
              playPause.setBackgroundResource(R.drawable.selpause);
              break;    
          }
          

          【讨论】:

            猜你喜欢
            • 2012-04-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多