为什么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
int
data. Because operations onbyte
,char
, orshort
values are internally promoted toint
, aswitch
whose expression evaluates to one of those types is compiled as though it evaluated to typeint
. If thechooseNear
method 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 typeint
for 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并不陌生.其在程序中的出镜 ...
随机推荐
- Django---进阶7
目录 图书管理的图书增删改查 choices参数(数据库字段设计常见) MTV与MVC模型 多对多三种创建方式 Ajax 小例子 作业 图书管理的图书增删改查 from django.shortcut ...
- [设计模式]面向对象五大设计原则:SOLID
SOLID (面向对象设计) 单一功能原则(Single responsibility principle) 每个类都应该有一个单一的功能,并且该功能应该由这个类完全封装起来 所有它的(这个类的)服务 ...
- JS的数据类型你真的懂了吗
一.JS数据类型分类 1.基本数据类型 (1)Number 数字 (2)String 字符串 (3)Boolean 布尔值 (4)null 空对象指针 (5)undefined 为定义 (6)symb ...
- P2295 MICE 网格中的DP
题目描述 分析 很好的一道网格中的\(DP\)题 我们设\(f[x][y]\)为小象到达坐标为\((x,y)\)的点时看到的最少的老鼠的数量 但是这样定义是不好转移的,因为小象可能从上面的格子转移下来 ...
- python numpy indexerror: too many indices for array
import numpy as np #data 原来数组 #arr_1 新数组 #将data的第一列赋值给arr_1的第一列 arr_1 = np.array((data.shape[0],5)) ...
- Elasticsearch恢复备份的数据
1.恢复备份好的snapshot 1.1恢复snapshot_1下的所有index POST _snapshot/my_backup/snapshot_1/_restore 1.2恢复snapshot ...
- Babel:下一代Javascript语法编译器
定义 Babel是一个Javascript的编译器,通过它你可以将一些新版本的ECMAScript语法转换成低版本的语法.以便能够在低版本的浏览器或者其它环境平稳运行. 截至目前笔者写这篇文章的时候, ...
- lua的table表去重
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 我的个人博客 方法一 用过lua的人都知道,lua的table中不允许存在相同的key,利用这个思想,我们可以将原始table ...
- oracle 启动报ORA-01105 ORA-19808
bash-4.4$ srvctl start instance -i jfcddb2 -d jfcddb PRCR-1013 : Failed to start resource ora.jfcddb ...
- smartJQueryZoom(smartZoom) 的使用方法
smartZoom 是一个我很喜欢用的库. 但是这个库有一些不完善的地方. 比如BUG. 比如使用上可能遇到的问题. <article> <div id="zoom_box ...