【问题标题】:Anonymous array indexing instead of a switch statement?匿名数组索引而不是 switch 语句?
【发布时间】:2011-09-09 08:06:45
【问题描述】:

在 Java 中,我发现以下代码比相应的庞大的 switch 语句更简洁且更易于维护:

try {
  selectedObj = new Object[] {
    objA,
    objB,
    objC,
    objD,
  }[unvalidatedIndex];
} catch (ArrayIndexOutOfBoundsException e) {
  selectedObj = objA;
}

反对

switch (unvalidatedIndex) {
  case 0:
    selectedObj = objA;
    break;

  case 1:
    selectedObj = objB;
    break;

  case 2:
    selectedObj = objC;
    break;

  case 3:
    selectedObj = objD;
    break;

  default:
    selectedObj = objA;
}

前者被认为是可接受的做法吗?我知道这不是最有效的,因为它涉及分配数组和捕获异常。当unvalidatedIndex 超出范围时(尽管处理了异常),是否会导致不受欢迎的事情?

如果可能的话,你会推荐一些更清洁的东西吗?

【问题讨论】:

    标签: java switch-statement indexoutofboundsexception anonymous-arrays


    【解决方案1】:

    你的第一种方法很好。

    但是,最好先检查索引:

    Object[] arr = new Object[] { ... };
    
    if (i < 0 || i >= arr.length)
        i = 0;
    selectedObj = arr[i];
    

    【讨论】:

    • 很好,但是这会污染命名空间,因为它只使用了一次额外的标识符arr。另一方面,如果使用匿名数组,arr.length 可以替换为常量4,但这会产生始终保持此常量和数组同步的维护成本。我知道我听起来很挑剔,但我是出于好奇才问这个的。
    • @Blagovest:将其包裹在{ } 中以创建内部范围并隐藏变量。或者创建一个 static 函数,它接受一个索引和一个 Object... 并返回一个对象。
    【解决方案2】:

    怎么样

    if(index < arr.length && index >= 0){
        obj = arr[index];
    }else{
        obj = defaultValue;
    }
    

    【讨论】:

      【解决方案3】:
          int index = 4;
      
          ArrayList<String> myObjects = Lists.newArrayList("a", "b", "c", "d");
          Object o = index  < myObjects.size() && index >= 0 ? myObjects.get(index) : null;
          System.out.println(o);
      

      Lists 来自 Guava。

      【讨论】:

      • 你真的不需要ArrayList。
      【解决方案4】:

      这是不可接受的做法。异常用于错误处理,而不是程序流。 例外情况也很慢。

      【讨论】:

        【解决方案5】:

        两者都是反模式。只需自己测试范围成员的索引即可。在许多实际情况下,可能有一种方法可以使用enum。

        【讨论】:

          【解决方案6】:

          就个人而言,虽然我毫不怀疑有些人会不同意,但我会这样做:

          switch (unvalidatedIndex) {
              case 0 : selectedObj = objA; break;
              case 1 : selectedObj = objB; break;
              case 2 : selectedObj = objC; break;
              case 3 : selectedObj = objD; break;
              default: selectedObj = objA; break;
              }
          

          它干净、紧凑、高效且非常易于理解。

          我会犹豫是否包括case 0,即default 案例。

          【讨论】:

            猜你喜欢
            • 2011-03-22
            • 2020-10-02
            • 1970-01-01
            • 1970-01-01
            • 2010-10-01
            • 2011-11-02
            • 1970-01-01
            • 2011-08-15
            • 2020-06-04
            相关资源
            最近更新 更多