一、基本用法
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标签没有放在最后,
但它仍然是最后被匹配的。
分享到:
相关推荐
- 编写简单的控制结构程序,如if-else语句、switch-case语句。 **挑战自我:** - 设计并实现一个简单的计算器程序,支持加减乘除四则运算。 - 编写一个程序,实现对输入文本的统计分析功能。 **招兵募马:** - ...
接着,会讲解控制流,如if语句、switch语句、for循环和while循环,这些都是编写逻辑代码的关键组成部分。 在面向对象编程方面,笔记将详细介绍类、对象、封装、继承和多态。类是Java中的蓝图,用于创建对象;对象是...
3. 控制结构:涵盖if-else语句、switch语句、for、while和do-while循环,了解如何控制程序流程,实现条件判断和重复执行。 4. 数组:学习创建、初始化和操作一维和多维数组,以及遍历数组的方法。 5. 函数(方法)...
2. **Java语法基础**:书中会详细讲解Java的基本语法,包括变量、数据类型、运算符、流程控制(如if语句、switch语句、循环结构等)、方法定义和调用,以及类和对象的创建。 3. **面向对象编程**:Java是面向对象的...
1. **基础语法**:Java的基础语法包括变量声明、数据类型(如整型、浮点型、字符型、布尔型等)、运算符(算术、关系、逻辑、位、赋值等)、流程控制(if-else、switch、for、while、do-while循环)、方法定义与调用...
1. **基础语法**:Java的基础语法包括变量声明、数据类型(如int、char、String)、运算符(如算术、比较、逻辑运算符)、流程控制语句(如if、for、while、switch)等。这些例子会展示如何正确地编写和组织Java代码...
1. **Java语言基础**:书中详细介绍了Java语言的基本语法,如数据类型、变量、运算符、流程控制语句(如if、for、while、switch)、方法定义与调用等,这些都是编程入门的基础。 2. **面向对象编程**:Java是一种...
3. **语法基础**:Java的语法结构与C++相似,但更简洁,包括数据类型(如整型、浮点型、字符型和布尔型)、变量声明、常量定义、运算符以及流程控制语句(如if-else、switch、for、while等)。 4. **类与对象**:...
2. 控制流:包括条件语句(if、switch)、循环语句(for、while、do-while)以及跳转语句(break、continue),这些构成了程序的逻辑结构。 3. 函数(方法):Java中的函数是代码复用的基础,通过参数传递和返回值...
通过这些实例,初学者能深入理解Java编程的基本概念和常用技巧,而有经验的开发者也可以温故知新,巩固基础。实践中学习和解决问题是提升编程技能的关键,这个压缩包中的55个实例正是为此目的而准备的。
1. **基础语法**:包括变量声明、数据类型(如整型、浮点型、字符型、布尔型)、运算符(算术、比较、逻辑、位操作等)、流程控制(if语句、switch语句、循环结构for、while、do-while)。 2. **类与对象**:这是...
这个"java-practice-main"可能包含了上述各个知识点的示例代码,通过实践这些代码,你可以更深入地理解和掌握Java编程。对于初学者来说,理解并实践这些概念是成为合格Java开发者的必经之路。对于有经验的开发者,...
【J2SE】应用编程150例是一个涵盖了Java基础到高级特性的实践教程,旨在帮助开发者通过实际操作深入理解Java编程。这个压缩包包含了150个精心设计的编程实例,每个例子都是一个独立的Java程序,覆盖了Java SE(标准...