Java Switch语句及性能剖析(转载补充)
一、基本用
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 }
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 }
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
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
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标签没有放在最后,
但它仍然是最后被匹配的。
个人补充: 由于现在的机器性能强劲, 系统的瓶颈更多是IO/DB等,一般不是if else 或者switch,mysql jdbc dirver源码中, 查询结果集resultSet.getObject("aaa")的时候使用的就是if else, 但是个人认为switch代码会使程序易读,易维护
原帖地址:http://blog.csdn.net/dc_726/article/details/7723497
相关推荐
### Java中的if语句和switch语句详解 #### 一、引言 在Java编程语言中,`if`语句和`switch`语句是非常重要的控制流语句,它们允许开发者根据不同的条件来控制程序的执行流程。这些语句不仅在逻辑判断中扮演着关键...
1. **switch语句基本结构**: ```java switch(expression) { case value1: // statements to be executed if expression matches value1 break; case value2: // statements to be executed if expression ...
5. **Switch语句的default分支**:在每个switch语句中包含default分支,确保所有可能的条件都得到处理,提高代码的健壮性。 6. **避免字符串字面量的重复定义**:如果一个字符串在多处被使用,应将其定义为常量,以...
`switch`语句在许多编程语言中都有实现,包括C、C++、Java、C#等。在本文中,我们将深入探讨`switch`语句的工作原理,尤其是通过汇编代码的角度来理解它。 首先,让我们看看`switch`语句的基本语法。一个典型的`...
### Java中switch的使用及语法说明 在Java编程语言中,`switch`语句是一种非常有用的控制结构,它允许程序基于一个表达式的值来选择执行不同的代码块。这对于需要根据不同条件执行不同操作的情况非常有用,尤其是在...
接下来,我们将深入分析在JDK 1.4环境下编写Java基础语句的关键点。 ### JDK 1.4简介 JDK 1.4是Java平台标准版的一个重要版本,发布于2002年。此版本引入了多个重要的新特性,包括正则表达式、日志框架(java.util...
根据给定文件的信息,我们可以提炼出以下几个关于Java循环语句的关键知识点: ### 1. Java中的选择结构 #### if-elseif-else 结构 在Java中,`if-elseif-else` 结构允许我们根据不同的条件执行不同的代码块。结构...
本文将通过详细的分析和实践示例,介绍 break 语句和 continue 语句在 Java 语言中的使用场景和方法。 一、Break 语句 Break 语句是 Java 语言中的一个流程控制语句,用于跳出当前的循环体或 switch 语句。Break ...
Java中的语句有多种形式,包括声明语句(声明变量或类)、表达式语句(执行表达式并可能产生副作用,如赋值操作),控制流语句(如if、for、while、do-while、switch等),和复合语句(使用花括号{}包围的一组语句)...
switch选择结构 目录 课程导入 掌握 switch 选择结构的语法 掌握 switch 选择结构的使用 【问题】根据学生的百分制成绩转化为等级制成绩并输出。 什么情况下使用switch选择结构 转化规则: 百分制成绩score 等级制...
在Java编程语言中,`switch`语句是一种用于实现多分支选择的控制结构,它提供了比`if...else if...else`更为简洁的代码形式。本文将深入探讨`switch`语句的概念、语法结构以及其在实际编程中的应用。 ### 1. `...
- **switch语句**:提供多路选择,适用于基于不同情况执行不同代码块。例如:`switch(表达式) { case 常量1: // 执行代码1 break; case 常量2: // 执行代码2 break; ... default: // 没有匹配的case时执行的代码 }`...
教师还会进行知识点分析,讲解if语句和switch语句的不同形式和适用场景。例如,if语句适用于boolean类型的判断和范围判断,而switch语句则适合处理多个常量值的匹配。 在案例演示中,通过输入月份来输出对应的季节...
* 控制流语句:包括if语句、switch语句、循环语句等。 * 函数:包括函数的定义和调用。 知识点5:游戏接宝类型的设计 游戏接宝类型的设计是指通过游戏的方式来设计和实现课程设计实验的要求,包括: * 游戏规则...
这可以通过条件语句(if-else)和switch语句实现。Java 8引入了函数式编程特性,可以使用lambda表达式和Stream API来创建更简洁、可读性更强的条件判断逻辑。例如,可以使用`Predicate`来定义复杂条件,并通过`...
1. **基础语法**:Java的基础包括变量、数据类型、运算符、控制结构(如if-else,switch,for,while等)、类与对象、封装、继承、多态等。理解这些概念是成为合格Java程序员的基础。 2. **面向对象**:Java是一种...
### Java就业面试题知识点解析:Switch语句适用性 #### 关键知识点概述 在Java编程语言中,`switch`语句是一种常用的流程控制结构,用于根据不同的条件执行不同的代码块。传统的`switch`语句主要支持整数类型的...
Java 数据结构测试题涉及到多个Java编程基础和设计概念,包括数据结构、软件设计工具、多分支语句(switch语句)、继承与多态、自定义表格模型以及并发控制。以下是这些知识点的详细解释: 1. **二分法查找**: - ...
在这个问题中,需要分析switch语句和变量作用域。在Java中,switch语句可以用于根据不同的条件执行不同的代码块。在这个代码中,switch语句用于根据字符digit的值执行不同的代码块。需要注意的是,变量j的作用域仅在...