为什么switch不支持long
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
intdata. Because operations onbyte,char, orshortvalues are internally promoted toint, aswitchwhose expression evaluates to one of those types is compiled as though it evaluated to typeint. If thechooseNearmethod had been written using typeshort, the same Java Virtual Machine instructions would have been generated as when using typeint. Other numeric types must be narrowed to typeintfor use in aswitch.
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的更多相关文章
- 【java】switch case支持的6种数据类型
switch表达式后面的数据类型只能是byte,short,char,int四种整形类型,枚举类型和java.lang.String类型(从java 7才允许),不能是boolean类型. 在网上看到 ...
- switch case 支持的 6 种数据类型!
有粉丝建议可以偶尔推送一些 Java 方面的基础知识,一方面可以帮助一初学者,也可以兼顾中高级的开发者. 那么今天就讲一下 Java 中的 switch case 语句吧,有忘记的同学正好可以温习一下 ...
- Java的switch是否支持String作为参数,还支持哪些类型?
在Java5以前,switch(expr)中,exper只能是byte,short,char,int类型. 从Java5开始,java中引入了枚举类型,即enum类型. 从Java7开始,exper还 ...
- 实测switch支持的参数类型
@Test public void testSwitch() { switch (2) { case 1: System.out.println("int型:" + 1); bre ...
- JDK1.7之后switch支持string
转自:https://blog.csdn.net/tjcyjd/article/details/9666035 在Java7之前,switch只能支持 byte.short.char.int或者其对应 ...
- Java jre7及以上版本中的switch支持String的实现细节
Java7中的switch支持String的实现细节 作者: zsxwing 更新: 2013-03-04 21:08:02 发布: 2012-04-26 13:58:19 在Java7之前,swit ...
- JDK语法糖之switch字串与枚举支持
在JDK1.7之前,switch只支持byte,short,char,int,注意1.5之后的自动拆箱,对应的这四种基础类型的封装类也同样支持Byte,Short,Character,Integer, ...
- Python 为什么不支持 switch 语句?
本文出自"Python为什么"系列,请查看全部文章 在这篇文章里,我们会聊一聊为什么 Python 决定不支持 switch 语句. 为什么想要聊这个话题呢? 主要是因为 swit ...
- 窥探Swift编程之强大的Switch
之前初识Swift中的Switch语句时,真的是让人眼前一亮,Swift中Switch语句有好多特有而且特好用的功能.说到Switch, 只要是写过程序的小伙伴对Switch并不陌生.其在程序中的出镜 ...
随机推荐
- Linux多任务编程之六:编写多进程程序及其代码(转)
来源:CSDN 作者:王文松 转自Linux公社 ------------------------------------------------------------------------- ...
- scrapy 基础组件专题(十四):scrapy CookiesMiddleware源码
一 Scrapy框架--cookie的获取/传递/本地保存 1. 完成模拟登陆2. 登陆成功后提取出cookie,然后保存到本地cookie.txt文件中3. 再次使用时从本地的cookie.txt中 ...
- 数据可视化基础专题(四):Pandas基础(三) mysql导入与导出
转载(有添加.修改)作者:但盼风雨来_jc链接:https://www.jianshu.com/p/238a13995b2b來源:简书著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处 ...
- Python之迭代器、装饰器、软件开发规范
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...
- 邂逅Vue.js
1.简单认识一下Vue.js Vue (读音 /vjuː/,类似于 view),不要读错. Vue是一个渐进式的框架,什么是渐进式的呢? p渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来更 ...
- 量子点/钙钛矿 LED的研究概述
注:参考文献和文章尚在整理ing... 一 常用术语 1.外量子效率(External quantum efficiency,EQE) 这是LED最重要的参数,它的定义为: 因此,EQE越大,发射到外 ...
- js:数组(创建、遍历、函数)
1.数组 采用单个变量只能存储一个数据,数组能够存储多个数据,获取方式也比较简单.它是将一组数据存储在当个变量下的存储方式. 2.数组的创建 (1)new方式创建,不指定数组长度 <script ...
- python mysql中in参数化说明
第一种:拼接字符串,可以解决问题,但是为了避免sql注入,不建议这样写 还是看看第二种:使用.format()函数,很多时候我都是使用这个函数来对sql参数化的 举个例子: select * from ...
- linux实现shell脚本监控磁盘内存达到阈值时清理catalina.out日志
想在服务器上写一个shell脚本,在磁盘使用率达到80%时,自动清理掉一些没有用的日志文件,根据这个想法,在生产环境上写了一个以下脚本,按照该流程,可实现在linux环境做一个定时任务来执行shell ...
- vue学习(六) 事件修饰符 stop prevent capture self once
//html <div id="app"> <div @click="divHandler" style="height:150px ...