一、基本用法
switch的case语句可以处理int,short,byte,char类型的值,但是不能处理long,String等类型。
因为short,byte,char都会转换成int进行处理,这一点也可以从生成的字节码看出。
- char a = 'e';
- switch (a) {
- case 'c':
- System.out.println("In case c");
- break;
- case 'd':
- System.out.println("In case d");
- break;
- default:
- System.out.println("In default");
- break;
- case 'e':
- System.out.println("In case e");
- break;
- }
0:bipush 101
2: istore_1
3: iload_1
4: tableswitch{ //99 to 101
99: 32;
100: 43;
101: 65;
default: 54 }
生成的字节码始终为bipush或iconst(小于5的整数),用于将整数压入栈。
二、新特性
在JDK 5中加入的枚举Enum类型也是可以作为case值的。
- Type t = Type.C;
- switch (t) {
- case A:
- System.out.println("In case A");
- break;
- case B:
- System.out.println("In case B");
- break;
- default:
- System.out.println("In default");
- break;
- case C:
- System.out.println("In case C");
- break;
- }
0: getstatic #18; //Field com/cdai/jdk/Type.C:Lcom/cdai/jdk/Type;
3: astore_1
4: invokestatic #24; //Method $SWITCH_TABLE$com$cdai$jdk$Type:()[I
7: aload_1
8: invokevirtual #27; //Method com/cdai/jdk/Type.ordinal:()I
11: iaload
12: tableswitch{ //1 to 3
1: 40;
2: 51;
3: 73;
default: 62 }
从字节码可以看出,对于枚举类型也是调用它的ordinal方法转成整型后进行switch匹配的。
在JDK 7中,又加入了对String类型的支持,从此不用再写If-Else来判断字符串了。
三、两种字节码
switch语句有两种编译结果:
当case中的值连续时,编译成tableswitch,解释执行时从table数组根据case值计算下标来取值,从数组中取到的
便是要跳转的行数。
- int a = 1;
- switch (a) {
- case 2:
- System.out.println("In case 2");
- break;
- case 3:
- System.out.println("In case 3");
- break;
- default:
- System.out.println("In default");
- break;
- case 1:
- System.out.println("In case 1");
- break;
- }
0: iconst_1
1: istore_1
2: iload_1
3:tableswitch{ //1 to 3
1: 61;
2: 28;
3: 39;
default: 50 }
28: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
31: ldc #22; //String In case 2
33: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
36: goto 69
39: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
42: ldc #30; //String In case 3
44: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
47: goto 69
50: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
53: ldc #32; //String In default
55: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
58: goto 69
61: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
64: ldc #34; //String In case 1
66: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
当case中的值不连续时,编译成lookupswitch,解释执行时需要从头到尾遍历找到case对应的代码行。
因为case对应的值不是连续的,如果仍然用表来保存case对应的行号,会浪费大量空间。
- int a = 10;
- switch (a) {
- case 2:
- System.out.println("In case 2");
- break;
- case 3:
- System.out.println("In case 3");
- break;
- default:
- System.out.println("In default");
- break;
- case 10:
- System.out.println("In case 10");
- break;
- }
0: bipush 10
2: istore_1
3: iload_1
4:lookupswitch{ //3
2: 40;
3: 51;
10: 73;
default: 62 }
40: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
43: ldc #22; //String In case 2
45: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
48: goto 81
51: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
54: ldc #30; //String In case 3
56: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
59: goto 81
62: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
65: ldc #32; //String In default
67: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
70: goto 81
73: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
76: ldc #34; //String In case 10
78: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
由此可以看出,这两种编译结果是编译器在考虑空间占用情况下,对代码效率进行的优化。
另外需要注意一点,就是不管是tableswitch还是lookupswitch,default标签都放在最后进行匹配,
但下面各个case和default语句块的顺序是与源代码相同的。所以尽管default标签没有放在最后,
但它仍然是最后被匹配的。
分享到:
相关推荐
用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载使用。用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载使用。用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载...
VBA语句集100句,集合常用的VBA语句,有空打开看看温故知新一下
机械军工行业:“温故知新”系列之工业机器人行业复盘(二):从美国汽车行业“2mm工程”看工业机器人国产化空间.pdf
20210202-银河证券-“温故知新”系列之工业机器人行业复盘(二):从美国汽车行业“2mm工程”看工业机器人国产化空间.pdf
涵盖java基础,通俗易懂,适用于初学者及温故知新者
最全的sqlserver查询脚本语句,和适合新手学习使用,高手也可以温故知新。
《Java基础复习笔记.docx》是一份宝贵的学习资源,旨在帮助那些已经具有一定Java编程基础的学习者巩固知识、进行复习以及更深入地理解Java编程的核心概念。以下是对这个资源的详细描述: 全面的复习内容:这份资源...
大四学期复习Java基础所产生的代码笔记,着重回顾了字符串、IO、线程以及socket套接字编程,在每一分代码中都附带了自己编程时的一些认识、笔记。适合Java基础不够踏实的童鞋。
温故知新ASP.NET 2.0(C#)温故知新ASP.NET 2.0(C#)温故知新ASP.NET 2.0(C#)温故知新ASP.NET 2.0(C#)温故知新ASP.NET 2.0(C#)
SpringSpringSpring温故知新六AOP向切面程Spring温故知新六AOP向切面程
计算机小数表示.温故知新.pdf
在学习Java中,常常碰到一种情况是:好不容易学会的知识点,没过半个月快忘干净了,又得重新捡起来温故知新; 有时候是知识点太多,代码敲少了没有实践也忘得快;于是我们依靠记笔记以及多敲代码来加强自己的记忆,...
数学:吃透课本温故知新.docx
积分管理系统java源码 new-and-old 温故: 资源的释放问题: java中需要手动释放的资源目前接触的主要有 1)io流资源 2)jdbc资源 关闭原则主要是先开后关,从里到外。 具体实现方法为放在try-catch-finally语句块...
初中语文文学讨论现当代文学温故知新
本文是异常内容的集大成者,力求全面,深入的异常知识研究与分析。本文由金丝燕网撰写,参考众多网上资源,经过内容辨别取舍,文字格式校验等步骤编辑而成,以飨读者。对于本文的内容,建议小白需要多多思考力求...
6) 平缓的学习曲线:学习使用JessMA只需掌握一定的Core Java与JSP/Servlet知识,本开发手册会循序渐进阐述每个知识点,每个知识点都会结合完整的示例进行讲述,知识点之间前后呼应,确保学习者在学习时温故知新,...
“温故知新”系列之工业机器人行业复盘(三):从零部件国产化看产业链协同发展(附报告).pdf
机械军工行业:“温故知新”系列之工业机器人行业复盘-从日德韩发展历程看中国工业机器人的未来.pdf