最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?switch語句支持哪些類型以及原理詳解

 更新時(shí)間:2025年08月06日 09:20:13   作者:洋風(fēng)子  
Java中的switch語句是一種多分支選擇結(jié)構(gòu),它允許一個(gè)變量的值等于多個(gè)不同的常量時(shí)執(zhí)行不同的代碼塊,這篇文章主要介紹了Java?switch語句支持哪些類型以及原理的相關(guān)資料,需要的朋友可以參考下

一、switch的底層實(shí)現(xiàn)原理

Java 中的 switch 語句核心是通過跳轉(zhuǎn)表(Jump Table) 實(shí)現(xiàn)高效分支跳轉(zhuǎn),其本質(zhì)是「用整數(shù)映射快速定位分支」。編譯器會(huì)根據(jù) case 值的分布,將 switch 編譯為兩種字節(jié)碼指令:

  • tableswitch:當(dāng) case 值是連續(xù)的整數(shù)范圍(如 1、2、3、4)時(shí)使用。跳轉(zhuǎn)表直接通過「整數(shù)偏移量」定位分支,時(shí)間復(fù)雜度為 O(1),效率極高。

  • lookupswitch:當(dāng) case 值是離散的整數(shù)(如 1、3、5、7)時(shí)使用。跳轉(zhuǎn)表會(huì)先對 case 值排序,再通過二分查找定位分支,時(shí)間復(fù)雜度為 O(log n),效率略低于 tableswitch。

無論是哪種指令,都要求判斷條件必須能轉(zhuǎn)換為整數(shù)且支持精確匹配—— 這是 switch 對類型的核心限制。

二、適用類型

整數(shù)類型(byte/short/int)

  • 底層邏輯: 整數(shù)類型本身就是「天然的整數(shù)標(biāo)識」,無需轉(zhuǎn)換即可直接作為跳轉(zhuǎn)表的索引。

  • 特殊說明:

    • byteshort 會(huì)被自動(dòng)提升為 int 后參與計(jì)算(因 Java 虛擬機(jī)運(yùn)算以 int 為最小單位)。

  • 示例代碼:

byte a= 1;
short b=2;
int c=3;
switch (c) {
    case 1: System.out.println("byte"); break;  // case值為連續(xù)整數(shù),編譯為tableswitch
    case 2: System.out.println("short"); break;  // 直接通過整數(shù)2定位此處
    case 3: System.out.println("int"); break;
    default: System.out.println("未知");
}

字符類型(char)

  • 底層邏輯: char 本質(zhì)是「Unicode 編碼的整數(shù)」(范圍 0~65535),例如字符 'A' 對應(yīng)整數(shù) 65,'中' 對應(yīng)整數(shù) 20013。編譯器會(huì)將 char 自動(dòng)轉(zhuǎn)換為對應(yīng)的整數(shù),再通過跳轉(zhuǎn)表定位分支,與整數(shù)類型的處理邏輯一致。

  • 示例代碼:

    char c = '中';
    switch (c) {
        case 'A': System.out.println("字母A(Unicode:65)"); break;
        case '中': System.out.println("漢字中(Unicode:20013)"); break;  // 匹配此處
        case '1': System.out.println("數(shù)字1(Unicode:49)"); break;
    }

枚舉類型(enum)

  • 底層邏輯: 每個(gè)枚舉常量都有一個(gè)內(nèi)置的 ordinal() 方法,返回其在枚舉定義中的「序號」(從 0 開始的整數(shù))。例如 enum Color {RED, GREEN, BLUE} 中,RED.ordinal()=0,GREEN.ordinal()=1。編譯器會(huì)將枚舉的 switch 轉(zhuǎn)換為對 ordinal() 結(jié)果的整數(shù) switch,本質(zhì)還是通過整數(shù)跳轉(zhuǎn)表實(shí)現(xiàn)。

  • 注意: 若枚舉類修改了常量順序(如插入新常量),ordinal() 的值會(huì)變化,可能導(dǎo)致 switch 邏輯出錯(cuò)。因此枚舉 switch 依賴于枚舉定義的穩(wěn)定性。

  • 示例代碼:

enum Season { SPRING, SUMMER, AUTUMN, WINTER }
Season s = Season.SUMMER;
switch (s) {
    case SPRING: System.out.println("春天(ordinal=0)"); break;
    case SUMMER: System.out.println("夏天(ordinal=1)"); break; 
    case AUTUMN: System.out.println("秋天(ordinal=2)"); break;
}
// 底層等價(jià)于:switch (s.ordinal()) { case 0: ... case 1: ... }

字符串類型(String,Java 7+ 支持)

  • 底層邏輯: 字符串本身不是整數(shù),但 Java 7 后通過「hashCode() 哈希值 + equals() 精確匹配」間接支持 switch,步驟如下:

    • 計(jì)算字符串的 hashCode()(32 位整數(shù),由字符序列決定);

    • switch 轉(zhuǎn)換為對哈希值的整數(shù) switch(用 lookupswitch 定位分支);

    • 因哈希可能沖突(不同字符串哈希值相同),需通過 equals() 二次驗(yàn)證字符串內(nèi)容,確保匹配正確。

  • 示例代碼

    String a = "Java";
    switch (a) {
        case "java": System.out.println("小寫java"); break;
        case "Java": System.out.println("大寫Java"); break;  // 匹配此處
        default: System.out.println("未知");
    }
    
    // 編譯器生成的等效邏輯:
    int hash = a.hashCode();  // "Java"的hashCode()為2301506
    switch (hash) {
        case 3254818:  // "java"的hashCode()
            if (a.equals("java")) { ... } 
            break;
        case 2301506:  // "Java"的hashCode()
            if (a.equals("Java")) {  // 二次驗(yàn)證防沖突
                System.out.println("大寫Java"); 
            }
            break;
    }

包裝類(Integer/Byte/Short/Character)

  • 底層邏輯: 包裝類通過自動(dòng)拆箱轉(zhuǎn)換為基本類型(如 Integerint),再按基本類型的邏輯處理。例如 Integer 會(huì)調(diào)用 intValue() 方法轉(zhuǎn)為 int,之后參與跳轉(zhuǎn)表計(jì)算。

  • 注意: 若包裝類為 null,自動(dòng)拆箱時(shí)會(huì)拋出 NullPointerException,需提前判空。

  • 示例代碼:

Integer score = 85;  // 包裝類
switch (score) {  // 自動(dòng)拆箱為 int 85
    case 90: System.out.println("優(yōu)秀"); break;
    case 85: System.out.println("良好"); break;  // 匹配此處
    case 60: System.out.println("及格"); break;
}

三、不適用類型及深層原因

浮點(diǎn)數(shù)(float/double)

  • 核心原因:浮點(diǎn)數(shù)存在精度丟失問題,無法實(shí)現(xiàn)「精確匹配」。

  • 例:十進(jìn)制的 0.1 轉(zhuǎn)換為二進(jìn)制時(shí),是一個(gè)無限循環(huán)的小數(shù)(類似十進(jìn)制的 1/3 = 0.3333...)。

  • 由于 floatdouble 的存儲空間有限(32 位和 64 位),只能存儲這個(gè)無限循環(huán)小數(shù)的前若干位,導(dǎo)致實(shí)際存儲的值與數(shù)學(xué)上的 0.1 存在微小誤差(即「精度丟失」)。

  • switch 支持浮點(diǎn)數(shù),可能出現(xiàn)與case 0.1 (整數(shù))無法匹配 的情況(因二進(jìn)制存儲不同),導(dǎo)致邏輯混亂.

長整型(long)

  • 核心原因:long 范圍過大(-9223372036854775808 ~ 9223372036854775807),無法構(gòu)建高效跳轉(zhuǎn)表。 跳轉(zhuǎn)表依賴「整數(shù)映射到內(nèi)存地址」,而 long 的值可能極其離散(如 1 和 10000000000),此時(shí) lookupswitch 的二分查找效率大幅下降,甚至可能比 if-else 更慢。Java 為保證 switch 的高效性,直接禁止 long 作為條件。

布爾類型(boolean)

  • 核心原因:設(shè)計(jì)上的「冗余性」—— booleantrue/false 兩個(gè)值,用 if-else 更簡潔,無需 switch 冗余語法。 若支持 boolean,switch (flag) { case true: ... case false: ... }if (flag) { ... } else { ... } 功能完全一致,但后者可讀性更高。

四、使用switch的關(guān)鍵注意事項(xiàng)

1. case 值必須是「編譯期常量」

case 后的值必須是編譯器可確定的常量,不能是普通變量。原因是跳轉(zhuǎn)表需要在編譯期確定所有可能的分支值 

int a = 10;
final int b = 10;  // final變量是常量
switch (a) {
    case a:  // ? 錯(cuò)誤:a是變量(非常量)
    case b:  // ? 正確:b是final常量(編譯期已知值)
        System.out.println("匹配10"); break;
}

2.字符串 switch 的額外注意

嚴(yán)格區(qū)分大小寫:"Java""java" 哈希值不同,視為不同分支。

避免 null:字符串為 null 時(shí)調(diào)用 hashCode() 會(huì)拋 NullPointerException,需提前判空。

String s = null;
if (s != null) {  // 先判空
    switch (s) { ... }
}

總結(jié)

switch 的核心是「整數(shù)映射跳轉(zhuǎn)表」,因此僅支持能轉(zhuǎn)換為整數(shù)且精確匹配的類型。

到此這篇關(guān)于Java switch語句支持哪些類型以及原理的文章就介紹到這了,更多相關(guān)Java switch語句詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的函數(shù)式編程Lambda、方法引用詳解

    Java中的函數(shù)式編程Lambda、方法引用詳解

    函數(shù)式編程通過引入函數(shù)來解決問題,強(qiáng)調(diào)輸入一致輸出一致,Lambda表達(dá)式是Java 8引入的一種簡潔的語法,用于替代匿名內(nèi)部類,簡化代碼并提高可讀性,本文給大家介紹Java—函數(shù)式編程(Lambda、方法引用),感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • btrace定位生產(chǎn)故障的方法示例

    btrace定位生產(chǎn)故障的方法示例

    這篇文章主要介紹了btrace定位生產(chǎn)故障的方法示例,文中通過示例代碼介紹的很詳細(xì),相信對大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-02-02
  • Java開發(fā)必備知識之?dāng)?shù)組詳解

    Java開發(fā)必備知識之?dāng)?shù)組詳解

    數(shù)組對于每一門編程語言來說都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語言對數(shù)組的實(shí)現(xiàn)及處理也不盡相同.本篇文章為大家整理了Java最全關(guān)于數(shù)組的知識點(diǎn),并給出其對應(yīng)的代碼,需要的朋友可以參考下
    2021-06-06
  • mybatis插入數(shù)據(jù)不返回主鍵id的可能原因及解決方式

    mybatis插入數(shù)據(jù)不返回主鍵id的可能原因及解決方式

    這篇文章主要介紹了mybatis插入數(shù)據(jù)不返回主鍵id的可能原因及解決方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Spring?AMQP?詳細(xì)介紹(最新推薦)

    Spring?AMQP?詳細(xì)介紹(最新推薦)

    SpringAMQP是Spring框架的高級消息隊(duì)列集成模塊,提供了與RabbitMQ等消息中間件的交互,支持聲明式編程、事務(wù)集成和可靠性機(jī)制,本文介紹Spring?AMQP?詳細(xì)知識,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Java 中的 xx ≠ null 是什么新語法

    Java 中的 xx ≠ null 是什么新語法

    Java中null是一個(gè)關(guān)鍵字,用來標(biāo)識一個(gè)不確定的對象。因此可以將null賦給引用類型變量,但不可以將null賦給基本類型變量。本文給大家分享Java 中的 xx ≠ null 是什么新語法,感興趣的朋友一起看看吧
    2021-06-06
  • 在非spring環(huán)境中調(diào)用service中的方法

    在非spring環(huán)境中調(diào)用service中的方法

    非Spring環(huán)境指的是不使用Spring框架來管理和配置應(yīng)用程序的運(yùn)行時(shí)環(huán)境,本文將給大家介紹如何在非spring環(huán)境中調(diào)用service中的方法,文中有詳細(xì)實(shí)現(xiàn)步驟,需要的朋友可以參考下
    2024-03-03
  • struts+spring+hibernate三個(gè)框架的整合

    struts+spring+hibernate三個(gè)框架的整合

    這篇文章主要介紹了struts+spring+hibernate三個(gè)框架的整合,需要的朋友可以參考下
    2017-09-09
  • SpringBoot實(shí)現(xiàn)子類的反序列化示例代碼

    SpringBoot實(shí)現(xiàn)子類的反序列化示例代碼

    這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)子類的反序列化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用SpringBoot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • idea使用Mybatis逆向工程插件詳情

    idea使用Mybatis逆向工程插件詳情

    這篇文章主要介紹了idea使用Mybatis逆向工程插件詳情,首先使用mybatis連接數(shù)據(jù)庫接著添加連接的mysql的信息,測試鏈接等過程,更多過程了解請參考下面文章的詳細(xì)內(nèi)容
    2022-01-01

最新評論

广河县| 莱芜市| 盐亭县| 保定市| 伽师县| 兖州市| 水城县| 措勤县| 定州市| 梨树县| 包头市| 门源| 大洼县| 卢湾区| 新密市| 巴南区| 柯坪县| 托里县| 页游| 抚州市| 大悟县| 赫章县| 康定县| 安宁市| 通辽市| 普宁市| 景泰县| 玉溪市| 和龙市| 湾仔区| 乃东县| 沾益县| 大丰市| 唐山市| 夏邑县| 肥东县| 霸州市| 西峡县| 阿坝县| 灯塔市| 夏邑县|