动力节点首页 全国咨询热线:400-8080-105

绑定手机号,登录
手机号

验证码

微信登录
手机号登录
手机号

验证码

微信登录与注册
微信扫码登录与注册

扫码关注微信公众号完成登录与注册
手机号登录
首页 > 文章

深入浅出学习switch语句

05-08 14:36 667浏览
举报 T字号
  • 大字
  • 中字
  • 小字

在Java语言中有很多的关键字,需要我们牢牢记住,switch便是其中很重要的一个。switch语句是Java控制语句里面非常基础的知识,也是老生常谈的内容。switch作为Java SE中的基本语句,switch语句的语法比较简单,相对也容易掌握。然而,大部分人却是知其然,不知其所以然。下面我们将深入去探索switch语句的用法。

首先我们看看switch 语法的基本格式:

switch (表达式) {

case 常量表达式或枚举常量:

语句;

break;

case 常量表达式或枚举常量:

语句;

break;

......

default: 语句;

break;

}

接下来我们来看看编译器对 switch表达式的各种类型的处理:

1.对包装类的处理

对包装类的处理是最简单的 —— 拆箱。看下面的例子,switch 比较的是包装类 Byte 。

Byte b = 2;
switch (b) {
case 1:
System.out.println("匹配成功");
break;
case 2:
System.out.println("匹配成功");
break;
}
用jad反编译一下这段代码,得到的代码如下:
Byte b = Byte.valueOf((byte)2);
switch(b.byteValue())
{
case 1: // '\001'
System.out.println("\u5339\u914D\u6210\u529F");
break;
case 2: // '\002'
System.out.println("\u5339\u914D\u6210\u529F");
break;
}

反编译的代码很简单,底层的switch比较的是Byte通过(拆箱)方法byteValue()得到的byte值。顺便说一下,这段反编译代码不仅揭开了 拆箱 的解析原理,也展示了 装箱 的解析原理(第一句代码);

2. 枚举类型

为了简单起见,直接采用JDK提供的枚举类型的线程状态类 Thread.state 类。

Thread.State state = Thread.State.RUNNABLE;
switch (state) {
case NEW:
System.out.println("线程处于创建状态");
break;
case RUNNABLE:
System.out.println("线程处于可运行状态");
break;
case TERMINATED:
System.out.println("线程结束");
break;
default:
break;
}

反编译代码:

Sex sex = Sex.MALE;
switch($SWITCH_TABLE$Test_2018_1_14$Sex()[sex.ordinal()])
{
case 1: // '\001'
System.out.println("sex:male");
break;
case 2: // '\002'
System.out.println("sex:female");
break;
}

从编译代码中发现,编译器对于枚举类型的处理,是通过创建一个辅助数组来处理,这个数组是通过一个$SWITCH_TABLE$java$lang$Thread$State() 方法创建的,数组是一个int[]类型数组,数组很简单,在每个枚举常量的序号所对应的数组下标位置的赋一个值,按序号大小赋值,从1开始递增。

3.对String类型的处理

依旧是先看个例子,再查看这个例子反编译代码,了解编译器的是如何解析的。

public static void main(String[] args) {
String s = "China";
switch (s) {
case "America":
System.out.println("匹配到美国");
break;
case "China":
System.out.println("匹配到中国");
break;
case "Japan":
System.out.println("匹配到日本");
default:
break;
}
}

反编译得到的代码:

public static void main(String args[])
{
String s = "China";
String s1;
switch((s1 = s).hashCode())
{
default:
break;
case 65078583:
if(s1.equals("China"))
System.out.println("\u5339\u914D\u5230\u4E2D\u56FD");
break;
case 71341030:
if(s1.equals("Japan"))
System.out.println("\u5339\u914D\u5230\u65E5\u672C");
break;
case 775550446:
if(s1.equals("America"))
System.out.println("\u5339\u914D\u5230\u7F8E\u56FD");
break;
}
}

从反编译的代码可以看出,switch 的String变量、case 的String常量都变成对应的字符串的 hash 值。也就是说,switch仍然没有超出它的限制,只是通过使用 String对象的hash值来进行匹配比较,从而支持 String 类型。

通过上面的例子我们不难看出,底层的switch只能处理4个基本类型的值。其他三种类型需要通过其他方式间接处理,即转成基本类型来处理。对枚举类型的处理,是通过枚举常量的序号及一个数组。而对字符串String的处理,是通过 String 的hash值。本文基本上已经很全面的对switch语句的用法进行了介绍,这也是借鉴了动力节点在线的Java SE视频课程中的内容,对其他的Java控制语句的讲解也很到位,感兴趣的小伙伴可以前去观看学习。

0人推荐
共同学习,写下你的评论
0条评论
代码小兵279
程序员代码小兵279

75篇文章贡献270037字

相关课程 更多>

作者相关文章更多>

推荐相关文章更多>

Java面试题及答案整理

提枪策马乘胜追击04-21 20:01

Spring常见面试题

代码小兵92504-17 16:07

Java零基础实战项目——五子棋

代码小兵98804-25 13:57

Java string类详解

杨晶珍05-11 14:54

6道经典算法面试题

杨晶珍05-12 16:39

发评论

举报

0/150

取消