目录

Switch语句长啥样?

Switch支持字符以及字符串的底层原理

为什么不支持long类型呢?


Switch语句长啥样?

public static void main(String[] args) {
        int num = 1;
        switch (num) {
            case 1:
                System.out.println("a");
                break;
            case 2:
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }
    }

JDK7之前支持的类型只有byte、short、char、int、integer、enum类型。而在JDK7时终于对字符串类型进行了适配。

Switch支持字符以及字符串的底层原理

对于如下这段代码,对其进行反编译

public class SwitchTest {
    public static void main(String[] args) {
        char ch = 'a';
        switch (ch) {
            case 'a':
                System.out.println("a");
                break;
            case 'b':
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }

        String str = "a";
        switch (str) {
            case "a":
                System.out.println("a");
                break;
            case "b":
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }
    }

}

反编译代码如下:

public class SwitchTest {
    public SwitchTest() {
    }

    public static void main(String[] args) {
        char ch = 97;
        switch (ch) {
            case 97:
                System.out.println("a");
                break;
            case 98:
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }

        switch ("a") {
            case "a":
                System.out.println("a");
                break;
            case "b":
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }

    }
}

可以看到对于字符类型来说,底层实际上比较的是 ascii 码,编译器会把char型变量转换成对应的 int 型变量。但发现字符串类型没有变化,难不成是完美适配?【不存在的,仅仅是因为博主的idea或者是jdk版本的问题没有看到它的真实面貌】

借用其它博主的case,代码如下:

public class switchDemoString {
    public static void main(String[] args) {
        String str = "world";
        switch (str) {
        case "hello":
            System.out.println("hello");
            break;
        case "world":
            System.out.println("world");
            break;
        default:
            break;
        }
    }
}

上述反编译后如下所示:

public class switchDemoString
{
    public switchDemoString()
    {
    }
    public static void main(String args[])
    {
        String str = "world";
        String s;
        switch((s = str).hashCode())
        {
        default:
            break;
        case 99162322:
            if(s.equals("hello"))
                System.out.println("hello");
            break;
        case 113318802:
            if(s.equals("world"))
                System.out.println("world");
            break;
        }
    }
}

这下可以知道原来字符串的 switch 是通过 equals() 和 hashCode() 方法来实现的。请记住,switch中只能使用整型,比如byte、short、char 以及 int。仔细看下可以发现,switch 块中实际是哈希值,然后通过使用 equals 方法比较进行安全检查,这个检查是必要的,因为哈希可能会发生碰撞。因此它的性能是不如使用枚举进行 switch 或者使用纯整数常量。Java编译器只增加了一个 equals 方法,如果你比较的是字符串字面量的话会非常快,比如”abc” ==”abc”。如果你把 hashCode() 方法的调用也考虑进来了,那么还会再多一次的调用开销。因为字符串一旦创建了,它就会把哈希值缓存起来。因此如果这个 switch 语句是用在一个循环里的,比如逐项处理某个值,或者游戏引擎循环地渲染屏幕,这里hashCode()方法的调用开销其实不会很大。

为什么不支持long类型呢?

在 stackoverflow 网站上也有人提出同样的问题

java中switch可以用来判断字符串吗 switch支持字符串java_算法

挑选出热度最高的评论

java中switch可以用来判断字符串吗 switch支持字符串java_控制语句_02

大致意思是,因为 switch 的设计初衷是对那些只有少数的几个值进行等值判断,如果值过于复杂,那么还是用 if 比较合适。