1. switch
语法中表达式值的数据类型可以有哪些
- 只能是
byte
、short
、int
、char
、enum
、String
(Java 7 以后)
2. 条件执行具体是怎么实现的
- 程序最终都是一条条的指令,CPU 有一个指令指示器,指向下一条要执行的指令,CPU 根据指示器的指示加载指令并执行。指令大部分是具体的操作和运算,在执行这些操作时,执行完一个操作后,指令指示器会自动指向挨着的下一条指令
- 有一些特殊指令,称为跳转指令,这些指令会修改指令指示器的值,让 CPU 跳到一个指定的地方执行。跳转有两种:一种是条件跳转;一种是无条件跳转。条件跳转检查某个条件,满足则进行跳转;无条件跳转则是直接进行跳转
- 在单一
if
的情况下可能不用无条件跳转指令,但稍微复杂一些的情况都需要。if
、if/else
、if/else if/else
、()?():()
都会转换为条件跳转和无条件跳转,但switch
不太一样
3. switch
实现原理是怎样的
switch
的转换和具体系统实现有关。如果分支比较少,可能会转换为跳转指令。如果分支比较多,使用跳转会进行很多次的比较运算,效率比较低- 可能会使用一种更为高效的方式,叫跳转表。跳转表是一个映射表,存储了可能的值以及要跳转到的地址
4. 跳转表结构为什么会更为高效呢
- 因为其中的值必须为整数,且按大小排序。按大小排序的整数可以使用高效的二分查找
- 如果值是连续的,则跳转表还会进行特殊优化,优化为一个数组,连找都不用找了,值就是数组的下标索引,直接根据值就可以找到跳转的地址。即使值不是连续的,但数字比较密集、差的不多,编译器也可能会优化为一个数组型的跳转表,没有的值指向
default
分支 - 程序源代码中的
case
值排列不要求是排序的,编译器会自动排序。之前说switch
值的类型可以是byte
、short
、int
、char
、enum
和String
。其中byte
、short
、int
本来就是整数;char
本质上也是整数;而enum
也有对应的整数;String
用于switch
时也会转换为整数
5. switch
值类型为什么不能是 long
类型
- 因为
switch
使用的跳转表值的存储空间一般为 32 位。也就是 4 个字节,容纳不下long
类型的值
6. switch
的值类型为什么可以是 String
String
是通过hashCode()
方法转换为整数的- 但不同
String
的hashCode
可能相同,跳转后会再次根据String
的内容进行比较判断
7. 一句话总结条件执行的实现原理
- 条件执行的本质依赖于条件跳转、无条件跳转、跳转表