我应该使用if then语句还是switch语句?

时间:2020-07-12 19:21:51

标签: java if-statement variables optimization switch-statement

我是Java开发的新手,从事Python已有大约一年的时间。我了解在将变量与多个不同值进行比较时如何使用switch语句,但是我的问题是,是否只有两个不同的值(即x == 1或x == 0)使用switch语句是否更合适还是一个if语句?我了解两者的工作原理,但是我无法弄清楚这种情况下是否会有区别,以及是否会有区别。

3 个答案:

答案 0 :(得分:0)

如果我没记错的话,开关会比其他/ if慢,所以这取决于您的用法。

答案 1 :(得分:0)

这取决于。如果您只有x==4之类的一个备选方案,并且只有两个操作,那么我将使用if语句。 例如,如果您有if(x==2||x==27||x==31){}else if(x==4||x==29||x==33){}else{},我将使用switch语句。在这种情况下,切换语句更具可读性:

switch(x){
  case 2:
  case 27:
  case 31:
          foo();
          break;
  case 4:
  case 29:
  case 33:
          bar();
          break;
  default:
          throw new IllegalArgumentException("Invalid value for x: "+x);
}

从性能POV中,我想说的是,如果速度更快,只有一些情况(2-4),之后我会进行切换声明

答案 2 :(得分:0)

长话短说:使用您喜欢的任何方式;

如果您对内部结构感兴趣,请继续阅读。我们不必猜测您问题的答案。我编写了一个简单的示例程序,让我们在实际的实现中看到它。首先,我将检查if-else,然后将检查switch

If-else

public class IfElse {

    public static void main(String[] args) {

        int x = Integer.valueOf(args[0]);

        if (x==1) {
            System.out.println("x is 1");
        } else {
            System.out.println("x is not 1");
        }
    }
}

现在,将其保存在简单的文本编辑器中并用javac IfElse.java进行编译后,Java编译器将生成一个IfElse.class文件,该文件具有以下字节码:

javap -c IfElse.class
Compiled from "IfElse.java"
public class IfElse {
  public IfElse();
    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: iconst_0
       2: aaload
       3: invokestatic  #2                  // Method java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;
       6: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
       9: istore_1
      10: iload_1
      11: iconst_1
      12: if_icmpne     26
      15: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      18: ldc           #5                  // String x is 1
      20: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      23: goto          34
      26: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      29: ldc           #7                  // String x is not 1
      31: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      34: return
}

切换

public class Switch {

    public static void main(String[] args) {
    
        int x = Integer.valueOf(args[0]);

        switch(x) {
            case 1:
                System.out.println("x is 1");
                break;
            default:
                System.out.println("x is not 1");
        }
    }
}

以相同的方式,我们用javac Switch.java进行编译,然后查看字节码:

Compiled from "Switch.java"
public class Switch {
  public Switch();
    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: iconst_0
       2: aaload
       3: invokestatic  #2                  // Method java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;
       6: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
       9: istore_1
      10: iload_1
      11: lookupswitch  { // 1
                     1: 28
               default: 39
          }
      28: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      31: ldc           #5                  // String x is 1
      33: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      36: goto          47
      39: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      42: ldc           #7                  // String x is not 1
      44: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      47: return
}

结论:

switch运算符具有:

  1. 需要编写更多的Java代码;

  2. 编译后的字节码更多。即:

     11: lookupswitch  { // 1
             1: 28
             default: 39
         }