switch 支持的类型

在 Java 语言规范里中,有说明 switch 支持的类型有:char、byte、short、int、Character、Byte、Short、Integer、String、enum。

​

为什么不支持 long ?

为什么只支持上面几种?int、String 都可以,为什么不支持 long ?

原因就是 switch 对应的 JVM 字节码 lookupswitch、tableswitch 指令只支持 int 类型。

下面是 JVM 规范中的说明(https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-3.html#jvms-3.10):

The Java Virtual Machine's tableswitch and lookupswitch instructions operate only on int data. Because operations on byte, char, or short values are internally promoted to int, a switch whose expression evaluates to one of those types is compiled as though it evaluated to type int. If the chooseNear method had been written using type short, the same Java Virtual Machine instructions would have been generated as when using type int. Other numeric types must be narrowed to type int for use in a switch.

byte、char、short 类型在编译期默认提升为 int,并使用 int 类型的字节码指令。所以对这些类型使用 switch,其实跟 int 类型是一样的。

​

为什么可以支持 String?

switch 支持 String 其实就是语法糖。编译器会根据字符串的 hashCode 来处理。

例:

String a = "aa";
switch (a) {
case "aa":
System.out.println("111");
break;
case "AaAa":
System.out.println("222");
break;
case "AaBB":
System.out.println("333");
break;
}

反编译后:

String var1 = "aa";
byte var3 = -1;
switch(var1.hashCode()) { // 第一个switch,根据hashCode计算第二个switch内的位置
case 3104:
if (var1.equals("aa")) {
var3 = 0;
}
break;
case 2031744:
if (var1.equals("AaBB")) {
var3 = 2;
} else if (var1.equals("AaAa")) {
var3 = 1;
}
} switch(var3) { // 第二个switch,执行原switch的逻辑
case 0:
System.out.println("111");
break;
case 1:
System.out.println("222");
break;
case 2:
System.out.println("333");
}

可以发现,会先根据 hashCode 找出原始 switch 内的位置,再执行原代码逻辑。

为什么用两个 switch ?

就是为了减少编译器的工作。

比如 switch 内有的 case 不写 break 等复杂情况,如果想直接根据 hashCode + equals 来只生成一个 switch,编译器就需要考虑各种情况。

所以目前编译器只做位置映射,第二部分直接按原 switch 来生成了。

​

关于 lookupswitch、tableswitch 可参考:你所不知道的Java之Switch

为什么switch不支持long的更多相关文章

  1. 【java】switch case支持的6种数据类型

    switch表达式后面的数据类型只能是byte,short,char,int四种整形类型,枚举类型和java.lang.String类型(从java 7才允许),不能是boolean类型. 在网上看到 ...

  2. switch case 支持的 6 种数据类型!

    有粉丝建议可以偶尔推送一些 Java 方面的基础知识,一方面可以帮助一初学者,也可以兼顾中高级的开发者. 那么今天就讲一下 Java 中的 switch case 语句吧,有忘记的同学正好可以温习一下 ...

  3. Java的switch是否支持String作为参数,还支持哪些类型?

    在Java5以前,switch(expr)中,exper只能是byte,short,char,int类型. 从Java5开始,java中引入了枚举类型,即enum类型. 从Java7开始,exper还 ...

  4. 实测switch支持的参数类型

    @Test public void testSwitch() { switch (2) { case 1: System.out.println("int型:" + 1); bre ...

  5. JDK1.7之后switch支持string

    转自:https://blog.csdn.net/tjcyjd/article/details/9666035 在Java7之前,switch只能支持 byte.short.char.int或者其对应 ...

  6. Java jre7及以上版本中的switch支持String的实现细节

    Java7中的switch支持String的实现细节 作者: zsxwing 更新: 2013-03-04 21:08:02 发布: 2012-04-26 13:58:19 在Java7之前,swit ...

  7. JDK语法糖之switch字串与枚举支持

    在JDK1.7之前,switch只支持byte,short,char,int,注意1.5之后的自动拆箱,对应的这四种基础类型的封装类也同样支持Byte,Short,Character,Integer, ...

  8. Python 为什么不支持 switch 语句?

    本文出自"Python为什么"系列,请查看全部文章 在这篇文章里,我们会聊一聊为什么 Python 决定不支持 switch 语句. 为什么想要聊这个话题呢? 主要是因为 swit ...

  9. 窥探Swift编程之强大的Switch

    之前初识Swift中的Switch语句时,真的是让人眼前一亮,Swift中Switch语句有好多特有而且特好用的功能.说到Switch, 只要是写过程序的小伙伴对Switch并不陌生.其在程序中的出镜 ...

随机推荐

  1. Django---进阶8

    目录 前后端传输数据的编码格式(contentType) ajax发送json格式数据 ajax发送文件 django自带的序列化组件(drf做铺垫) ajax结合sweetalert 批量插入 分页 ...

  2. mysql两种重要的引擎

    其中MyISAM:不支持事物,表锁 .frm : 表结构定义文件 .MYD: 表数据 .MYI:索引文件 InnoDB:支持事物,行锁 .frm : 表结构定义文件 .ibd:表空间(数据和索引)

  3. NEST教程系列:推断索引名

    NEST教程系列:三种推断索引名写法 目录 NEST教程系列:三种推断索引名写法 连接时设置默认索引 设置 .NET 类映射索引名 在创建请求的时候直接显式指定索引名 总结 连接时设置默认索引 构建 ...

  4. 02 Vue指令

    Vue指令 1.文本相关指令 <div id="app"> <!-- 插值表达式 --> <p>{{ msg }}</p> < ...

  5. scala 数据结构(九):-filter、化简

    1 filter filter:将符合要求的数据(筛选)放置到新的集合中 应用案例:将 val names = List("Alice", "Bob", &qu ...

  6. shell专题(四):Shell中的变量

    4.1 系统变量 1. 常用系统变量 $HOME.$PWD.$SHELL.$USER等 2.案例实操 (1)查看系统变量的值 [atguigu@hadoop101 datas]$ echo $HOME ...

  7. 数据可视化之DAX篇(十九)值得你深入了解的函数:SUMMARIZE

    https://zhuanlan.zhihu.com/p/66424209 SUMMARIZE函数非常强大,掌握以后表面上看也非常好用,所以我专门写篇文章介绍一下这个函数,至于是否一定要使用该函数,请 ...

  8. bzoj4396[Usaco2015 dec]High Card Wins*

    bzoj4396[Usaco2015 dec]High Card Wins 题意: 一共有2n张牌,Alice有n张,Bob有n张,每一局点数大的赢.知道Bob的出牌顺序,求Alice最多能赢几局.n ...

  9. C++11多线程编程--线程创建

    参考资料 adam1q84 我是一只C++小小鸟 Thread support library Book:<C++ Concurrency in Action> 线程的创建 线程的创建有多 ...

  10. 足球动图gif(二)