if..else代码:package breakan.test;import java.util.Scanner;public class Test2 {
public static void main(String[] args) {
Scanner scaner = new Scanner(System.in);
String str = scaner.next();
if(str == null){
System.out.println("null");
}else if (str.equals("a")){
System.out.println("apple");
}else if (str.equals("b")){
System.out.println("banana");
}else if (str.equals("c")){
System.out.println("candy");
}
}
}
改为以下形式:package breakan.test;import java.util.Scanner;public class Test {
public static void main(String[] args) {
Scanner scaner = new Scanner(System.in);
String str = scaner.next();
boolean[] results = { str == null, str.equals("a"), str.equals("b"), str.equals("c") };
for (int i = 0; i < results.length; i++) {
if (results[i]){
switch(i){
case 0:
System.out.println("null");
break;
case 1:
System.out.println("apple");
break;
case 2:
System.out.println("banana");
break;
case 3:
System.out.println("candy");
break;
}
}
}
}
}
以上只是示例,真正使用的时候可能会有10几个。
不过这样就需要把所有条件先判断了。
大家觉得这样写行么?
public static void main(String[] args) {
Scanner scaner = new Scanner(System.in);
String str = scaner.next();
if(str == null){
System.out.println("null");
}else if (str.equals("a")){
System.out.println("apple");
}else if (str.equals("b")){
System.out.println("banana");
}else if (str.equals("c")){
System.out.println("candy");
}
}
}
改为以下形式:package breakan.test;import java.util.Scanner;public class Test {
public static void main(String[] args) {
Scanner scaner = new Scanner(System.in);
String str = scaner.next();
boolean[] results = { str == null, str.equals("a"), str.equals("b"), str.equals("c") };
for (int i = 0; i < results.length; i++) {
if (results[i]){
switch(i){
case 0:
System.out.println("null");
break;
case 1:
System.out.println("apple");
break;
case 2:
System.out.println("banana");
break;
case 3:
System.out.println("candy");
break;
}
}
}
}
}
以上只是示例,真正使用的时候可能会有10几个。
不过这样就需要把所有条件先判断了。
大家觉得这样写行么?
MAN("男人"),WOMEN("女人");
private final String value;
Gender(String value){
this.value = value;
}
public String getValue() {
return value;
}
}
public static void main(String[] args){
for(Gender gender : Gender.values()){
System.out.println(gender.value);
}
}
}
不知道LZ具体的业务,所以也不好说
比如
public class Test2 {
public static void main(String[] args) {
Scanner scaner = new Scanner(System.in);
String str = scaner.next();
Map<String, String> map = new HashMap<String, String>();
map.put("a", "apple");
map.put("b", "banana");
map.put("c", "candy");
if(str == null){
System.out.println("null");
}else {
System.out.println(map.get(str));
}
}
}
为了使汇编代码与Java的情况更接近,这里用与Java比较相似的C#编码: static void Main(string[] args)
{
int a = 3; if (a == 0)
Console.WriteLine("零");
else if (a == 1)
Console.WriteLine("一");
else if (a == 2)
Console.WriteLine("二");
else if (a == 3)
Console.WriteLine("三");
switch (a)
{
case 0:
Console.WriteLine("零");
break;
case 1:
Console.WriteLine("一");
break;
case 2:
Console.WriteLine("二");
break;
case 3:
Console.WriteLine("三");
break;
}
}反汇编后的代码为: int a = 3;
00000041 mov dword ptr [ebp-40h],3 if (a == 0)
00000048 cmp dword ptr [ebp-40h],0
0000004c setne al
0000004f movzx eax,al
00000052 mov dword ptr [ebp-44h],eax
00000055 cmp dword ptr [ebp-44h],0
00000059 jne 0000006A
Console.WriteLine("零");
0000005b mov ecx,dword ptr ds:[022B2088h]
00000061 call 785424C0
00000066 nop
00000067 nop
00000068 jmp 000000CD
else if (a == 1)
0000006a cmp dword ptr [ebp-40h],1
0000006e setne al
00000071 movzx eax,al
00000074 mov dword ptr [ebp-44h],eax
00000077 cmp dword ptr [ebp-44h],0
0000007b jne 0000008C
Console.WriteLine("一");
0000007d mov ecx,dword ptr ds:[022B208Ch]
00000083 call 785424C0
00000088 nop
00000089 nop
0000008a jmp 000000CD
else if (a == 2)
0000008c cmp dword ptr [ebp-40h],2
00000090 setne al
00000093 movzx eax,al
00000096 mov dword ptr [ebp-44h],eax
00000099 cmp dword ptr [ebp-44h],0
0000009d jne 000000AE
Console.WriteLine("二");
0000009f mov ecx,dword ptr ds:[022B2090h]
000000a5 call 785424C0
000000aa nop
000000ab nop
000000ac jmp 000000CD
else if (a == 3)
000000ae cmp dword ptr [ebp-40h],3
000000b2 setne al
000000b5 movzx eax,al
000000b8 mov dword ptr [ebp-44h],eax
000000bb cmp dword ptr [ebp-44h],0
000000bf jne 000000CD
Console.WriteLine("三");
000000c1 mov ecx,dword ptr ds:[022B2094h]
000000c7 call 785424C0
000000cc nop
switch (a)
000000cd mov eax,dword ptr [ebp-40h]
000000d0 mov dword ptr [ebp-48h],eax
000000d3 mov eax,dword ptr [ebp-48h]
000000d6 cmp eax,4
000000d9 jae 000000E2
000000db jmp dword ptr [eax*4+01251678h]
000000e2 nop
000000e3 jmp 00000121
{
case 0:
Console.WriteLine("零");
000000e5 mov ecx,dword ptr ds:[022B2088h]
000000eb call 785424C0
000000f0 nop
break;
000000f1 nop
000000f2 jmp 00000121
case 1:
Console.WriteLine("一");
000000f4 mov ecx,dword ptr ds:[022B208Ch]
000000fa call 785424C0
000000ff nop
break;
00000100 nop
00000101 jmp 00000121
case 2:
Console.WriteLine("二");
00000103 mov ecx,dword ptr ds:[022B2090h]
00000109 call 785424C0
0000010e nop
break;
0000010f nop
00000110 jmp 00000121
case 3:
Console.WriteLine("三");
00000112 mov ecx,dword ptr ds:[022B2094h]
00000118 call 785424C0
0000011d nop
break;
0000011e nop
0000011f jmp 00000121
}
}
代码较长,我在这里只说明下两种方式的运行原理:
if-else if
先判断a==0是否成立,成立则执行语句块,执行完后跳出(jmp 000000CD);
不成立则跳到第一个else(jne 0000006A,注:000006a为else if(a==1)程序段的首行),再判断当前条件(a==1)是否成立,方法同上,不成立则跳到下一else(0000008c),如此循环。
可见,与a匹配的条件越靠后,所执行的判断与跳转次数就越多。switch-case
首先,编译程序会在编译期为switch结构组织一张表(就是上面出现的地址01251678h),它里面存放的是每一个case块的首地址。而每个地址在表中的偏移量为case n:里面的n。
在进行switch运算时,程序会先判断操作数a是否超过case各项的取值范围(这里是a>=4时超过范围),如果超过则直接跳转到switch块后面(cmp eax,4; jae 000000E2; jmp 00000121)(如果有default块,这里会跳转到default块的首地址)。
如果没超过就会用a值作偏移量从表中查出对应case块的首地址再跳转(jmp dword ptr [eax*4+01251678h])
由于32位机的变址也是32位(4Byte),所以计算偏移量时还要对乘4。
可见,不管a为何值,switch结构只需经过1次比较,1次乘法、1次加法2次算术运算,再加1次跳转就能找到相应的代码地址。
if(str == null){
System.out.println("null");
}else if (str.equals("a")){
System.out.println("apple");
}else if (str.equals("b")){
System.out.println("banana");
}else if (str.equals("c")){
System.out.println("candy");
}
JDK7.0
支持switch(String string){
case "":...break;
case "":...break;
}