文档章节

Java7中的switch支持String的实现细节

Freewheel
 Freewheel
发布于 2015/09/26 11:00
字数 680
阅读 468
收藏 0
在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。在Java7中,呼吁很久的String支持也终于被加上了。
 
例如,下面是一段switch中使用String的示例代码。
 
01 public class Test {
02  
03     public void test(String str) {
04         switch(str) {
05         case "abc":
06             System.out.println("abc");
07             break;
08         case "def":
09             System.out.println("def");
10             break;
11         default:
12             System.out.println("default");
13         }
14     }
15  
16 }
 
在switch语句中,String的比较用的是String.equals,因此大家可以放心的使用。
需要注意的是,传给switch的String变量不能为null,同时switch的case子句中使用的字符串也不能为null。
为什么要有这些非null的限制呢?其实,我们只要将这段代码反汇编出来,看一下底层到底是如何实现的,就可以明白了。下面是汇编出来的代码。
 
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:     aload_0
   1:     invokespecial     #1; //Method java/lang/Object."":()V
   4:     return
 
public void test(java.lang.String);
  Code:
   0:     aload_1
   1:     astore_2
   2:     iconst_m1
   3:     istore_3
   4:     aload_2
   5:     invokevirtual     #2; //Method java/lang/String.hashCode:()I
   8:     lookupswitch{ //2
          96354: 36;
          99333: 50;
          default: 61 }
   36:     aload_2
   37:     ldc     #3; //String abc
   39:     invokevirtual     #4; //Method java/lang/String.equals:(Ljava/lang/Object;)Z
   42:     ifeq     61
   45:     iconst_0
   46:     istore_3
   47:     goto     61
   50:     aload_2
   51:     ldc     #5; //String def
   53:     invokevirtual     #4; //Method java/lang/String.equals:(Ljava/lang/Object;)Z
   56:     ifeq     61
   59:     iconst_1
   60:     istore_3
   61:     iload_3
   62:     lookupswitch{ //2
          0: 88;
          1: 99;
          default: 110 }
   88:     getstatic     #6; //Field java/lang/System.out:Ljava/io/PrintStream;
   91:     ldc     #3; //String abc
   93:     invokevirtual     #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   96:     goto     118
   99:     getstatic     #6; //Field java/lang/System.out:Ljava/io/PrintStream;
   102:     ldc     #5; //String def
   104:     invokevirtual     #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   107:     goto     118
   110:     getstatic     #6; //Field java/lang/System.out:Ljava/io/PrintStream;
   113:     ldc     #8; //String default
   115:     invokevirtual     #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   118:     return
 
}
 
估计有些同学懒得看这些汇编,其实把上面的汇编代码用Java写出来就是下面的样子了。
写到这里,大家应该能明白为什么不能用null了吧。
 
01 public class Test {
02     public void test(String str) {
03         int i = -1;
04         switch(str.hashCode()) {
05         case 96354: // "abc".hashCode()
06             if (str.equals("abc")) {
07               i = 0;
08             }
09             break;
10         case 99333: // "def".hashCode()
11             if (str.equals("def")) {
12               i = 1;
13             }
14             break;
15         default:
16             break;
17         }
18  
19         switch(i) {
20         case 0:
21             System.out.println("abc");
22             break;
23         case 1:
24             System.out.println("def");
25             break;
26         default:
27             System.out.println("default");
28         }
29     }
30 }
 
如果switch传入的null,那么在运行时对一个null对象调用hashCode方法会出现NullPointerException。
如果switch的case写的是null,那么在编译时无法求出hashCode,因此在编译时就会报错了。
 
switch支持String只是一个语法糖,由javac来负责生成相应的代码。底层的JVM在switch上并没有进行修改。

本文转载自:http://blog.iamzsx.me/show.html?id=161001

Freewheel
粉丝 11
博文 83
码字总数 48265
作品 0
普陀
程序员
私信 提问
java程序员修炼之道

第一部分:用Java7做开发 第一章:初识java7 1.1语言与平台《Java语言规范(JLP)》《JVM规范(VMSpec)》 1.2Coin项目:浓缩的都是精华 修改过程:1.更新JLS 2.在源码编译器中实现一个原型 3.为修改...

zhchl2010
2015/09/20
83
0
一起学Java7新功能扩展——深入历险分享(一)

特此声明:因网友疑问,这里声明一个重要的安全,就是大家所知的java惊现0day漏洞!8月30日,Oralce紧急发布了新版本的JDK和JRE,原因是发现了一个严重的0day漏洞CVE-2012-4681,远程攻击者可...

Beyond-Bit
2012/09/03
4.2K
26
深入理解Java 7(笔记)

switch Java 7 中新增加了对String的支持,除此之外还支持int、char、byte、short及其封装类Integer、Character、Byte、Short。对于基本类型的支持我们很容易理解,但是String类型使用了不同...

chris_2009
2016/03/30
107
0
Java7的新特性1-project coin

Project coin project coin是Java一些语法改进的一个项目。 Strings in switch 在Java1.7之前,switch语句只能是byte、char、short和int以及包装类和枚举常量,比如: 在Java7中,扩展了允许...

mushui
2013/07/29
807
4
小菜修炼之道——Java7新特性

1、TWR 自动关闭资源 自动关闭资源必须要注意书写规范,所有需要关闭的资源必须使用一个变量声明出来并且写在try的小括号块中,不是大括号。如下代码: try( InputStream is = new FileInpu...

learn_more
2015/08/17
121
0

没有更多内容

加载失败,请刷新页面

加载更多

只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生。 比较通用的返回值格式如下:...

晓月寒丶
昨天
59
0
区块链应用到供应链上的好处和实际案例

区块链可以解决供应链中的很多问题,例如记录以及追踪产品。那么使用区块链应用到各产品供应链上到底有什么好处?猎头悬赏平台解优人才网小编给大家做个简单的分享: 使用区块链的最突出的优...

猎头悬赏平台
昨天
28
0
全世界到底有多少软件开发人员?

埃文斯数据公司(Evans Data Corporation) 2019 最新的统计数据(原文)显示,2018 年全球共有 2300 万软件开发人员,预计到 2019 年底这个数字将达到 2640万,到 2023 年达到 2770万。 而来自...

红薯
昨天
65
0
Go 语言基础—— 通道(channel)

通过通信来共享内存(Java是通过共享内存来通信的) 定义 func service() string {time.Sleep(time.Millisecond * 50)return "Done"}func AsyncService() chan string {retCh := mak......

刘一草
昨天
58
0
Apache Flink 零基础入门(一):基础概念解析

Apache Flink 的定义、架构及原理 Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态或无状态的计算,能够部署在各种集群环境,对各种规模大小的数据进行快速...

Vincent-Duan
昨天
60
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部