preface

A little sister with a switch multiple choice question to ask me.

The reason I answer this question with certainty is not because I know how it works, but because someone in a group asked me the same kind of question, I glanced at it and remembered the answer, so I copied it.

The little sister then asked me why, I said that there was less break, but if I asked again: why there was less break, the result would be different, I could not answer. So, to nip the awkwardness in the bud, study the role of break in switch.

Start with bytecode

So the convention is to write the demo first.

 public static void main(String[] args) {
    int i = 0;
    switch (i) {
        case 0:
            System.out.println(0);
        case 1:
            System.out.println(1);
        case 2:
            System.out.println(2);
  }
Copy the code

Run the code and the result is as follows:

Case 0 matches case 1 and case 2. Very confusing! Follow the conventional wisdom and see if bytecode can give us an answer.

javacCompile andjavapTo view:

Tableswitch and lookupswitch are both used for switch conditional jumps. The former is used for consecutive case values, such as 0, 1, and 2 in the preceding code. The latter is used for case value discontinuities.

As you can see from the bytecode, case conditions in the switch are separated from the corresponding code block. As shown in the figure above, when case is 0, jump to the code labeled 28; When it is 1, jump to the code of label 35; When is 2, jump to the code of label 43; Default jumps to the 49 code.

When case 0 matches, jump directly to the code labeled 28 and start executing, output 0, and then ride gallop, all the way down the hill, execute all the following codes in sequence until the code labeled 49 return, the method is finished and the program is finished.

If case 0 matches, skip to 28, execute 28, 31, 32 and output 0, then skip to 49. So, how should this “hop” be represented in bytecode?

With the return? That won’t work, because the return will terminate the method, so the code can’t execute after the switch. How to do that….

About goto

Goto: indicates an unconditional jump. Goto 1 indicates the jump to the code labeled 1.

Write another code sample, this time giving each case a break in the code.

  public static void main(String[] args) {
      int i = 0;
      switch (i) {
          case 0:
              System.out.println(0);
              break;
          case 10:
              System.out.println(1);
              break;
          case 2:
              System.out.println(2);
              break;
      }
      System.out.println("Hello World");
  }
Copy the code

Recompile and look at the bytecode.

As shown, compared with the first bytecode, there are GOto instructions at labels 35 and 45. If case 0 matches successfully, it will skip to label 28. After executing instructions 31 and 32 corresponding to the code block, goTO instruction 35 will jump to label 55, thus jumping out of the scope of switch, and case 1 and 2 will not be executed.

Wait, there’s a goto missing, there should be a goto above 55! In fact, this involves compiler optimization techniques. The last GOto is also an instruction that jumps to label 55, but the next line is executed in the same order without the GOTO, so the goto is eliminated as useless code by the compiler.

Switch is different from if

Use if to implement the switch logic above.

  public static void main(String[] args) {
      int i = 0;
      if (i == 0) {
          System.out.println(0);
      } else if (i == 1) {
          System.out.println(1);
      } else if (i == 2) {
          System.out.println(2); }}Copy the code

Compile to bytecode:

If_icmpne is used to compare two ints. The difference between if and switch can also be seen from the bytecode: if conditions and code blocks are in order, switch conditions and code blocks are separate; If automatically generates a GOto instruction, while switch generates a GOto instruction only when break is added.

conclusion

The break in case tells the front-end compiler to add a GOto to the end of each case block. This way, after executing the matched code, you can skip the following case code block.

Sure enough, the desire to learn new knowledge is the motivation.

Public number: entry to give up the road, looking forward to your attention.