Should I use an if then statement or a switch statement?
I am new to java development, having done python for about a year. I understand how switch statements are used when comparing a variable to multiple different values, but my question is if there are only two different values, (ie. x == 1 or x == 0) is it more optimal to use a switch statement or an if else statement? i understand how both work but I just can’t figure out if there would be a difference in this case, and if there is what it would be.
If I am not wrong, switchs are slower than else/if, so that is something to know about depending on your usage.
It depends. If you have only one alternative like x==4
and only two actions, I would go with an if-statement. If you have for example if(x==2||x==27||x==31){}else if(x==4||x==29||x==33){}else{}
I would go with a switch statement. In this cases a switch-statement is more readable:
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); }
From a performance POV I would say, if is faster, if there are only some cases (2-4), after that I would a switch-statement
Long story short: use whichever you like to use;
If you’re interested into internals, then keep reading. We don’t have to guess the answer on your question. I’ve written a simple example program and let’s see it in the actual implementation. First I’ll examine if-else
, and then I’ll examine 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"); } } }
Now, after we save this in the simple text editor and compile it with javac IfElse.java
, Java compiler will generate a IfElse.class
file which has the following bytecode:
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 }
Switch
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"); } } }
in the same way, we compile it with javac Switch.java
and see the bytecode afterwards:
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 }
Conclusion:
switch
operator has:
-
a bit more Java code to be written;
-
a bit more bytecode after compilation. Namely this:
11: lookupswitch { // 1 1: 28 default: 39 }