Java 中 switch 语句支持字符串类型的历史和原理

开发 前端
为了让 switch​ 语句更高效,编译器还会做一些优化。比如,如果 case​ 标签不多,编译器可能会直接用一系列的 if-else​ 语句来代替 switch​ 语句。

想象一下这个场景:你正在写一个水果识别的程序,用户输入「苹果」就要执行特定逻辑。在 Java 7 之前,你只能这样写:

if (fruit.equals("苹果")) {
    // 处理苹果
} else if (fruit.equals("香蕉")) {
    // 处理香蕉
} else {
    //... 其他水果
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

这种写法就像超市收银员每次结账都要拆开包裹检查商品,而 Java 7 之后的字符串 switch 相当于给每个商品贴了快速识别条形码-程序员写代码更优雅。

以前为什么不能用字符串?

早期的 Java(Java 7 以前)switch 只能处理数字类数据(比如 int、char),因为这些类型底层可以直接用数字比对,简单快速。而字符串是复杂对象,直接逐个字符对比太费时间,所以那时候只能用 if-else 处理字符串分支。

字符串的“身份证”——哈希码(Hash Code)

每个字符串都有个唯一的哈希码(可以理解成根据内容用数学公式算出来的身份证号):

  • • 比如 "苹果" 的哈希码是 12345,"香蕉" 的哈希码是 67890
  • • 关键特性:内容相同的字符串哈希码一定相同,不同内容大概率不同(极小概率重复,叫“哈希碰撞”)

switch 字符串操作

1. 存身份证号编译器会把所有 case 后的字符串(比如 "苹果"、"香蕉")的哈希码存进一个数组里。

2. 先比身份证号运行到 switch 时,先计算输入字符串的哈希码(比如用户输入 "苹果",算出 12345),然后去数组里快速匹配。

3. 再验真身(防冒牌货)哈希码匹配后,还要用 equals() 方法确认字符串内容是否真的相同(防止极小概率的哈希碰撞)。

从本质来讲,switch 对字符串的支持,其实也是 int 类型值的匹配。

举个栗子 🌰

String fruit = "苹果";
switch(fruit) {
    case "苹果": 
        System.out.println("红富士"); 
        break;
    case "香蕉": 
        System.out.println("芝麻蕉"); 
        break;
    default: 
        System.out.println("不认识");
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

在这个例子中,编译器会先计算 "苹果" 和 "香蕉" 的哈希码,然后在运行时计算 fruit 的哈希码。如果 fruit 的哈希码和 "苹果" 的哈希码匹配,它会再用 equals 方法确认 fruit 是否真的是 "苹果"。如果是,就输出 "红富士"。

编译器的优化

为了让 switch 语句更高效,编译器还会做一些优化。比如,如果 case 标签不多,编译器可能会直接用一系列的 if-else 语句来代替 switch 语句。这样做可以减少 hashCode 计算和 equals 方法调用的次数,从而提高性能。

性能考虑

虽然字符串类型的 switch 语句很方便,但它毕竟需要计算哈希码 hashCode 和调用 equals 方法,所以在性能要求非常高的场合,可能不如用整数类型或枚举类型来得快。比如,在一些对速度要求极高的游戏中,开发者可能会选择用整数或枚举类型来避免额外的性能开销。switch 语句让编程变得更加灵活,但也需要注意它的性能特点,合理选择适用的场景。

责任编辑:武晓燕 来源: 沐雨花飞碟
相关推荐

2021-03-08 08:23:24

Java字符串截取

2009-09-04 10:26:09

Java和C#字符串类

2024-07-03 08:24:58

2010-09-13 15:12:26

sql server字

2009-06-08 21:45:46

Javaswitch-case

2011-06-08 15:45:41

字符串JAVA

2009-11-30 14:08:42

PHP字符串原理

2010-03-09 15:15:02

Python字符串类型

2010-11-26 13:18:53

MySQL字符串

2019-12-17 15:49:44

Java语言字符串

2022-12-27 08:13:40

JAVA字符串常量池

2010-06-28 15:18:51

SQL Server

2010-11-26 10:58:30

MySQL字符串

2023-10-26 12:01:30

Golang字符串

2013-12-02 09:43:29

字符串编程

2021-07-30 06:22:37

C++字符型字符串

2009-06-23 14:13:00

Java字符串

2023-12-18 09:26:12

C++switchif

2020-10-09 06:48:19

Pythonswitch语句

2010-09-06 17:30:46

SQL函数
点赞
收藏

51CTO技术栈公众号