专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

switch表达式中可以用哪些类型

switch语句是一个很容易忽略的语法点,在表达式支持的类型上也犯过很多错,今天就来整理一下

switch语句基本定义:

switch (表达式){
    case 值1: 
        语句体1;
        break;
    case 值2:
        语句体2;
        break;
    ...

    default:
        语句体n+1;
        break;
}

break在switch语句中的作用

关于breakswitch语句的使用可以参考这篇博客https://tech.souyunku.com/EthanWong/p/13190595.html

表达式的取值

表达式的取值类型

1、 在JDK6及以前,表达式只能是一个常量表达式或枚举常量。所以表达式的取值可以是:

 *  `byte`、`short`、`int`、`char`四种基本类型,以及其包装类型
 *  `Enum`枚举类型

2、 在JDK7以后新增支持String类型

编译器对表达式取值的处理

虽然随着JDK版本迭代,支持的新类型越来越多,但是在编译的字节码层次,switch语句还是只能支持基本的四种类型。

1、 基本类型的处理

**`int`数据类型**
    int a = 2;
    switch (a)
        {
            case 1: 
                System.out.println("first");
                break;

            case 2: 
                System.out.println("second");
                break;

            case 3: 
                System.out.println("second");
                break;

            default:
                System.out.println("null");
                break;
        }

反编译后的代码
    byte byte0 = 2;
            switch (byte0)
            {
            case 1: // '\001'
                System.out.println("first");
                break;

            case 2: // '\002'
                System.out.println("second");
                break;

            case 3: // '\003'
                System.out.println("second");
                break;

            default:
                System.out.println("null");
                break;
            }

其实从这里就可以看出,正是因为`int`和`byte`、`char`、`short`之间可以隐式转换。所以可以直接支持其对应的四种包装类型

**`char`类型的处理**
    char c = '2';
    switch (c)
        {
            case '1': 
                System.out.println("first");
                break;

            case '2': 
                System.out.println("second");
                break;

            case '3': 
                System.out.println("second");
                break;

            default:
                System.out.println("null");
                break;
        }

反编译后的代码:
    byte byte0 = 50;
            switch (byte0)
            {
            case 49: // '1'
                System.out.println("first");
                break;

            case 50: // '2'
                System.out.println("second");
                break;

            case 51: // '3'
                System.out.println("second");
                break;

            default:
                System.out.println("null");
                break;
            }

从代码来看,底层是通过比较字符的ASCII码来进行判断的。

2、 包装类型的处理

    Integer I = 4;
    switch (I)
        {
            case 1: 
                System.out.println("first");
                break;

            case 2: 
                System.out.println("second");
                break;

            case 3: 
                System.out.println("second");
                break;

            default:
                System.out.println("null");
                break;
        }

经过反编译后的代码是
    Integer integer = Integer.valueOf(4);
            switch (integer.intValue())
            {
            case 1: // '\001'
                System.out.println("first");
                break;

            case 2: // '\002'
                System.out.println("second");
                break;

            case 3: // '\003'
                System.out.println("second");
                break;

            default:
                System.out.println("null");
                break;
            }

从反编译的代码中可以看出,`Integer`装箱的时候自动调用`Integer`的`valueof(int)`方法,拆箱的时候是自动调用`Integer`的`intValue`方法。对应到其他包装类型和Integer也类似。

3、 枚举类型的处理

    public enum ColorEnum{
        RED,GREEN,YELLOW;
    }

    public class EnumTest{
        public static void main(String args[]){
            ColorEnum color = ColorEnum.YELLOW;
            switch(color){
                case RED:
                    System.out.println("Stop");
                    break;
                case GREEN:
                    System.out.println("Pass");
                    break;
                case YELLOW:
                    System.out.println("Wait");
                    break;
                default:
                    System.out.println("null");
                    break;
            }
        }
    }

反编译:
    // Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://kpdus.tripod.com/jad.html
    // Decompiler options: packimports(3) fieldsfirst ansi space 
    // Source File Name:   EnumTest.java

    import java.io.PrintStream;

    public class EnumTest
    {

        public EnumTest()
        {
        }

        public static void main(String args[])
        {
            ColorEnum colorenum = ColorEnum.YELLOW;
            static class 1
            {

                static final int $SwitchMap$ColorEnum[];
                //自动生成int数组,通过编号来表示枚举
                static 
                {
                    $SwitchMap$ColorEnum = new int[ColorEnum.values().length];
                    try
                    {
                        $SwitchMap$ColorEnum[ColorEnum.RED.ordinal()] = 1;
                    }
                    catch (NoSuchFieldError nosuchfielderror) { }
                    try
                    {
                        $SwitchMap$ColorEnum[ColorEnum.GREEN.ordinal()] = 2;
                    }
                    catch (NoSuchFieldError nosuchfielderror1) { }
                    try
                    {
                        $SwitchMap$ColorEnum[ColorEnum.YELLOW.ordinal()] = 3;
                    }
                    catch (NoSuchFieldError nosuchfielderror2) { }
                }
            }

            switch (1..SwitchMap.ColorEnum[colorenum.ordinal()])
            {
            case 1: // '\001'
                System.out.println("Stop");
                break;

            case 2: // '\002'
                System.out.println("Pass");
                break;

            case 3: // '\003'
                System.out.println("Wait");
                break;

            default:
                System.out.println("null");
                break;
            }
        }
    }

从反编译的代码可以看出,底层通过创建`$SwitchMap$ColorEnum[]`的`int`数组,并通过数组的编号来表示枚举。

4、 String类型的处理

    public class StringTest{
        public static void main (String args[]){
            String s = "RED";
            switch(s){
                case RED:
                    System.out.println("红色");
                    break;
                case GREEN:
                    System.out.println("绿色");
                    break;
                case YELLOW:
                    System.out.println("黄色");
                    break;
                default:
                    System.out.println("null");
                    break;
            }
        }
    }

反编译后:
    // Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://kpdus.tripod.com/jad.html
    // Decompiler options: packimports(3) fieldsfirst ansi space 
    // Source File Name:   StringTest.java

    import java.io.PrintStream;

    public class StringTest
    {

        public StringTest()
        {
        }

        public static void main(String args[])
        {
            String s = "RED";
            String s1 = s;//创建string对象
            byte byte0 = -1;
            switch (s1.hashCode())
            {
            case 81009: //string常量用hash值表示
                if (s1.equals("RED")) //避免hash碰撞,用equals辅助判断
                    byte0 = 0;
                break;

            case 68081379: 
                if (s1.equals("GREEN"))
                    byte0 = 1;
                break;

            case -1680910220: 
                if (s1.equals("YELLOW"))
                    byte0 = 2;
                break;
            }
            switch (byte0)
            {
            case 0: // '\0'
                System.out.println("红色");
                break;

            case 1: // '\001'
                System.out.println("绿色");
                break;

            case 2: // '\002'
                System.out.println("黄色");
                break;

            default:
                System.out.println("null");
                break;
            }
        }
    }

从代码中可以看出,在对`String`类型的处理中,是通过对常量的hash值和equals方法来判断比较。

文章永久链接:https://tech.souyunku.com/38505

未经允许不得转载:搜云库技术团队 » switch表达式中可以用哪些类型

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们