Talk about the mysteries switch keyword

Switch Syntax

switchAs Java built-in keywords, but actually used in the project is relatively small. About switch, still there are some mysteries of.

To what switch, I have the if-else

Indeed, the project used switcha relatively small main reason is that its effects could be if-elsereplaced Moreover, switchrestrictions on the type, but also hindered the switchfurther use.

Take a look at switchthe syntax:

switch(exp){
    case exp1:
        break;
    case exp2:
        break;
    default:
        break;
}

Wherein expthe type is limited to: byte ,short , int , char,its packaging, and enumeration and String(JDK1.7)

Why have these restrictions?

If we say that switchthe function and if-elsethe same, then the meaning of its existence where?

The answer is: switchand if-elsethe time in the design, there is a certain difference in performance.

Look at the code:

public class Test {

    public static void switchTest(int a) {

        switch (a) {
            case 1:
                System.out.println("1");
                break;
            case 2:
                System.out.println("2");
                break;
            default:
                System.out.println("3");
                break;
        }
    }
}
javap  -c Test.class

The results are as follows:

  public static void switchTest(int);
    Code:
       0: iload_0
       1: lookupswitch  { // 2
                     1: 28
                     2: 39
               default: 50
          }
          
    ...

There is some code omitted.

It can be found switchthrough the lookupswitchinstructions. Then the lookupswitchcommand is doing it?

In Java se8 described in the document you may probably know:

switchIt can be compiled into two instructions

  • lookupswitch: When switchthe casesparse time, the use of the command intvalues caseone by one comparison, until it finds the corresponding case(look here, can be optimized for the binary search)
  • tableswitch: When switcha casemore intensive when used casevalue as switchthe index, can be found in the case of the corresponding time complexity is O (1) is case(the HashMap is analogous)

And documentation as well as a description:

Java virtual machine tableswitchand lookupswitchinstructions only intdata is valid. Because byte, charor or shortthe operation inside the values promoted int, so its switchexpression evaluates to compile one type, if it is calculated to be the same type int. If the chooseNearmethod is to use a type of writing, the type of use shortwill generate the same Java virtual machine instructions int. Other types must be reduced to a digital type intfor use in a switch.

Now, we should be able to understand why switchkeywords will have restrictions on the type, because the switchkeyword is translated is limited to the type int , int as to why, I guess it should be based on considerations of performance and complexity to achieve it .

Types other than int

We understand byte,shor,char,intthat can be used as switchthe type, and then look enumerationString

public static void switchTest(String a) {

        switch (a) {
            case "1":
                System.out.println("1");
                break;
            case "2":
                System.out.println("2");
                break;
            default:
                System.out.println("3");
                break;
        }
    }

Compiled Test.class. IDEA dragged decompile obtained the following code:

   public static void switchTest(String a) {
        byte var2 = -1;
        switch(a.hashCode()) {
        case 49:
            if (a.equals("1")) {
                var2 = 0;
            }
            break;
        case 50:
            if (a.equals("2")) {
                var2 = 1;
            }
        }

        switch(var2) {
        case 0:
            System.out.println("1");
            break;
        case 1:
            System.out.println("2");
            break;
        default:
            System.out.println("3");
        }

    }

You can see, JDK7 supported Stringtype is by getting Stringto choose the hashCode, that is, in essence, is int. Why Stringbe so dry? It depends on Stringa constant class.

In order to prevent hash collisions, the insurance code more were equalsjudged.

Let's look atEnum

public static void switchTest(Fruit a) {
    switch (a) {
        case Orange:
            System.out.println("Orange");
            break;
        case Apple:
            System.out.println("Apple");
            break;
        default:
            System.out.println("Banana");
            break;
    }

}

Compiled Test.class. IDEA dragged decompile obtained the following code:

    public static void switchTest(Fruit a) {
        switch(1.$SwitchMap$com$dengchengchao$Fruit[a.ordinal()]) {
        case 1:
            System.out.println("Orange");
            break;
        case 2:
            System.out.println("Apple");
            break;
        default:
            System.out.println("Banana");
        }

    }

It can be seen enumerate support switchmore simple, direct by order of enumeration can be as relevantcase

In short:

  • switchLogically, design, than if-elseto be fast, but in 99.99% of cases, they are about the same performance, unless casea huge amount of branches, but caseunder excessive fragmentation, the general should consider using a multi-state reconstruction.
  • switchWhile supporting byte,int,short,char,enum,Stringbut essentially all intother compiler just help you make a syntactic sugar optimize it.

Respect for labor, reproduced indicate the source


If you thought that it was good, welcome attention to the micro-channel public number: Yat tour Java, every day from time to time publish articles related to Java advanced, thanks to attention

Guess you like

Origin www.cnblogs.com/dengchengchao/p/11839910.html