if和if-else之间有什么明显的区别吗?

时间:2010-04-20 19:00:36

标签: java coding-style maintainability

鉴于以下代码片段,是否存在明显的差异?

public boolean foo(int input) {
   if(input > 10) {
       doStuff();
       return true;
   }
   if(input == 0) {
       doOtherStuff();
       return true;
   }

   return false;
}

VS。

public boolean foo(int input) {
   if(input > 10) {
      doStuff();
      return true;
   } else if(input == 0) {
      doOtherStuff();
      return true;
   } else {
      return false;
   }
}

或者使用这段代码,单退出原则会更好......

public boolean foo(int input) {
   boolean toBeReturned = false;
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   }

   return toBeReturned;
}

有任何明显的性能差异吗?你觉得一个人或多或少比其他人更易于维护/阅读吗?

9 个答案:

答案 0 :(得分:10)

在第二个例子中,您非常清楚地说明两个条件是相互排斥的 对于第一个,它不是那么清楚,并且在(不太可能的)事件中,在两个ifs之间添加input的赋值,逻辑将改变。
假设将来有人在第二个if之前添加input = 0 当然这不太可能发生,但是如果我们在这里谈论可维护性,如果 - 否则清楚地表明存在相互排斥的条件,而一堆ifs则没有,并且它们彼此之间没有那么依赖。 - 块。

编辑:现在我看到,在这个特定的例子中,return子句强制相互排他性,但同样,我们讨论的是可维护性和可读性。

无论如何,关于性能,如果用Java编码你不应该关心几个if块的性能,如果它是在一个非常慢的硬件中嵌入C,也许,但肯定不是用java。

答案 1 :(得分:4)

使用最能描述您意图的任何形式。

如果事情很简单,不要遵循单退出原则 - 这只会让它更加混乱。

答案 2 :(得分:4)

  • 在第一个:

    有人最终会因为一些奇怪的原因,当你不看时会添加一些补充声明,这会使这种方法在某些奇怪的条件下失败,每个人(或者最差的,一个人)将花费4小时。观察源代码并调试应用程序,最终发现中间有一些东西。

  • 第二个肯定更好,不仅可以防止这种情况,而且还有助于明确说明,这个这个不再。

    如果我们在if内写的所有代码最多10行,这实际上并不重要,但遗憾的是并非如此,还有其他程序员因某种原因认为是if body应该是>无论如何,总共200行......

  • 我不喜欢第三种,它强迫我查找返回变量,并且更容易找到return关键字

关于速度表现,它们(几乎)相同。别担心。

答案 3 :(得分:1)

在上一个例子中,不要这样做:

public boolean foo(int input) {
   boolean toBeReturned = false;
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   }

   return toBeReturned;
}

但是这(注意使用Java的 final ):

public boolean foo(int input) {
   final boolean toBeReturned;    // no init here
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   } else {
      toBeReturned = false;
   }
   return toBeReturned;
}

通过这样做你可以清楚地表达你的意图,这是支持“按意图编程”的IDE的天赐之物(没有必要“编译”以查看潜在的错误,即使在部分AST上,一个好的IDE可以检查不完整的源代码实时并给你即时警告)。

这样您确定不要忘记初始化您的返回值。如果你以后决定毕竟还需要另一个条件,那就太棒了。

我一直这样做,甚至更多,因为我开始使用IntelliJ IDEA(很久以前的版本4左右),这给我带来了许多愚蠢的分心错误......

有些人会争辩说,对于这样一个简单的案例来说,这是太多的代码,但这完全忽略了这一点:关键是要明确意图,以便代码可以轻松读取,以后可以轻松扩展,而不会意外忘记分配 toBeReturned 并且不小心忘记从后面的句子中返回,你可以添加。

否则,如果“简洁”是游戏的名称,那么我会写:

public boolean foo(int a) {
  return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false; 
}

doStuff doOtherStuff 都会返回true。

答案 4 :(得分:0)

语义 - 没有。性能方面,这取决于编译器,即它是否能够发现两个条件不能同时成立。我敢打赌标准的Sun编译器可以。是否使用单出口原则取决于口味。我个人讨厌它。

答案 5 :(得分:0)

版本#1和#2可能比#3快,但我认为性能差异很小。我宁愿专注于可读性

就个人而言,我永远不会使用版本#2。在#1和#3之间,我会选择能够为相关案例生成最可读代码的那个。我不喜欢我的方法中的许多退出点,因为它使代码难以分析。但是,有些情况下,当我们立即退出某些特殊情况时,流程会变得更清晰,并继续主要案例。

答案 6 :(得分:0)

当两个例子不相似时,请考虑这种情况:

    public boolean foo(int input) {
        if (input > 10) {
            // doStuff();
            return true;
        }
        System.out.println("do some other intermediary stuff");
        if (input == 0) {
            // doOtherStuff();
            return true;
        }

        return false;
    }

VS

    public boolean foo(int input) {
        if (input > 10) {
            // doStuff();
            return true;
        } 
        //System.out.println("doing some intermediary stuff... doesn't work");
        else if (input == 0) {
            // doOtherStuff();
            return true;
        } else {
            return false;
        }
        return false;
    }

第一种方法可能更灵活,但两种公式都可以在不同情况下使用。

关于性能,我认为对于任何常规Java应用程序来说,差异都很小,需要由理智的程序员编写:)。

答案 7 :(得分:0)

在你的情况下第二个如果第一个if只会被调用,如果第一个失败所以它在这里不太重要但是如果你的第一个if做了什么并且没有返回,那么第二个if(那将总是假的)仍然是测试,除非它在else-if。

换句话说,有些情况下if-else-if和if-if之间的区别很重要,但这不是其中之一。

示例:尝试此操作,然后在删除else后尝试此操作。你得到两个不同的输出:

int someNumber = 1;
if(someNumber < 5)
{
    someNumber += 5;
    Console.WriteLine("First call.");
}
else if(someNumber >= 5)
{
    Console.WriteLine("Second call.");
}

答案 8 :(得分:-1)

在第一个和第二个片段之间,确实没有区别。然而,第三个片段效率很低。因为您等待将程序的控制权返回给调用者,直到方法中的最后一行代码,否则会浪费处理能力/内存,而前两个代码片段会在确定其中一个条件为真后立即返回控制。 / p>