else 在 return 之后,来自 if 语句的第一部分

Else after return from first part of an if statement

库的 BigInteger.gcd(...) 方法的实现以这些语句开始:

public BigInteger gcd(BigInteger val) {
    if (val.signum == 0)
        return this.abs();
    else if (this.signum == 0)
        return val.abs();
    ...
}

在这种情况下,else 关键字的用途是什么?它只是程序员忘记删除的旧代码的残余,还是以某种方式影响性能?

我理解,在这种特殊情况下,从语义上讲,带和不带 else 的版本是相同的。然而,我经常面临

之间的选择
<Some method signature>(...) {
    if (...) {
        <Short branch>
        return ...;
    } else {
        <Long branch>
        return ...;
    }
}

<Some method signature>(...) {
    if (...) {
        <Short branch>
        return ...;
    }
    <Long branch>
    return ...;
}

哪个选项在性能方面更好(请注意,这个问题是 Java 特定的)?如果两种情况下的性能几乎相同,那么哪一种在可读性方面更好?

在我的机器上,使用 java 1.8.0_172,这两个版本产生相同的字节码。所以这是在编译时本身优化的。在这两种情况下,JIT 编译器会看到相同的输入,因此运行时性能将相同。

其他版本:

public class MyTest {
    public static void main(String[] args) {
        if (args.length > 2) {
                System.out.println("More than 2");
                return;
        } else {
                System.out.println("Hello");
        }
    }
}

无其他版本:

public class MyTest {
    public static void main(String[] args) {
        if (args.length > 2) {
                System.out.println("More than 2");
                return;
        }
        System.out.println("Hello");
    }
}

然后用java MyTest.java编译它们,然后用javap -c MyTest得到字节码,比较两个源的字节码。它们是相同的。两者都生成以下字节码:

Compiled from "MyTest.java"
public class MyTest {
  public MyTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: aload_0
       1: arraylength
       2: iconst_2
       3: if_icmple     15
       6: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       9: ldc           #3                  // String More than 2
      11: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      14: return
      15: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      18: ldc           #5                  // String Hello
      20: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      23: return
}

现在为了可读性,这当然是主观的。我更喜欢没有不必要的 else.

的版本

我的 0.02 美元价值:当面临选择时

<Some method signature>(...) {
    if (...) {
        <Short branch>
        return ...;
    } else {
        <Long branch>
        return ...;
    }
}

<Some method signature>(...) {
    if (...) {
        <Short branch>
        return ...;
    }
    <Long branch>
    return ...;
}

只要可能,我喜欢选择选项 3:

<Some method signature>(...) {
    T result;        
    if (...) {
        <Short branch>
        result = ...;
    } else {
        <Long branch>
        result = ...;
    }
    return result;

对于像这样的简单案例,我喜欢方法的单一逻辑结束(即 return 语句)与其物理结束一致。

效率更高? 疑。

高效?可能不会。

更具可读性? 这么认为,但我不能保证你会这么认为,也不能证明你应该这么认为。

只是把它扔在那里。