请先阅读:
package org.example.condition;
public class ConditionDemo {
public static void main(String[] args) {
demoA(true);
demoA(false);
demoB(-2);
demoB(1);
demoB(3);
demoB(1024);
}
private static void demoA(boolean tag) {
if (tag) {
System.out.println("This is ture");
} else {
System.out.println("This is false");
}
}
private static void demoB(int num) {
if (num <= 0) {
System.out.println("This is 1");
} else if (num > 0 && num < 3) {
System.out.println("This is 2");
} else if (num == 3) {
System.out.println("This is 3");
} else {
System.out.println("This is something else");
}
}
}
运行如下命令:
javap -c -p -v ConditionDemo.class
得到的字节码为:
Classfile /C:/Data/Code/GitHub/GeekbangJavaTrainingCamp/Week_01/Course_01/bytecode/target/classes/org/example/condition/ConditionDemo.class
Last modified Oct 20, 2020; size 1062 bytes
MD5 checksum 63dd9a9fecccbd7dfb0fe1618f961105
Compiled from "ConditionDemo.java"
public class org.example.condition.ConditionDemo
minor version: 0
major version: 51
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #12 // org/example/condition/ConditionDemo
super_class: #13 // java/lang/Object
interfaces: 0, fields: 0, methods: 4, attributes: 1
Constant pool:
#1 = Methodref #13.#36 // java/lang/Object."<init>":()V
#2 = Methodref #12.#37 // org/example/condition/ConditionDemo.demoA:(Z)V
#3 = Methodref #12.#38 // org/example/condition/ConditionDemo.demoB:(I)V
#4 = Fieldref #39.#40 // java/lang/System.out:Ljava/io/PrintStream;
#5 = String #41 // This is ture
#6 = Methodref #42.#43 // java/io/PrintStream.println:(Ljava/lang/String;)V
#7 = String #44 // This is false
#8 = String #45 // This is 1
#9 = String #46 // This is 2
#10 = String #47 // This is 3
#11 = String #48 // This is something else
#12 = Class #49 // org/example/condition/ConditionDemo
#13 = Class #50 // java/lang/Object
#14 = Utf8 <init>
#15 = Utf8 ()V
#16 = Utf8 Code
#17 = Utf8 LineNumberTable
#18 = Utf8 LocalVariableTable
#19 = Utf8 this
#20 = Utf8 Lorg/example/condition/ConditionDemo;
#21 = Utf8 main
#22 = Utf8 ([Ljava/lang/String;)V
#23 = Utf8 args
#24 = Utf8 [Ljava/lang/String;
#25 = Utf8 demoA
#26 = Utf8 (Z)V
#27 = Utf8 tag
#28 = Utf8 Z
#29 = Utf8 StackMapTable
#30 = Utf8 demoB
#31 = Utf8 (I)V
#32 = Utf8 num
#33 = Utf8 I
#34 = Utf8 SourceFile
#35 = Utf8 ConditionDemo.java
#36 = NameAndType #14:#15 // "<init>":()V
#37 = NameAndType #25:#26 // demoA:(Z)V
#38 = NameAndType #30:#31 // demoB:(I)V
#39 = Class #51 // java/lang/System
#40 = NameAndType #52:#53 // out:Ljava/io/PrintStream;
#41 = Utf8 This is ture
#42 = Class #54 // java/io/PrintStream
#43 = NameAndType #55:#56 // println:(Ljava/lang/String;)V
#44 = Utf8 This is false
#45 = Utf8 This is 1
#46 = Utf8 This is 2
#47 = Utf8 This is 3
#48 = Utf8 This is something else
#49 = Utf8 org/example/condition/ConditionDemo
#50 = Utf8 java/lang/Object
#51 = Utf8 java/lang/System
#52 = Utf8 out
#53 = Utf8 Ljava/io/PrintStream;
#54 = Utf8 java/io/PrintStream
#55 = Utf8 println
#56 = Utf8 (Ljava/lang/String;)V
{
public org.example.condition.ConditionDemo();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lorg/example/condition/ConditionDemo;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iconst_1
1: invokestatic #2 // Method demoA:(Z)V
4: iconst_0
5: invokestatic #2 // Method demoA:(Z)V
8: bipush -2
10: invokestatic #3 // Method demoB:(I)V
13: iconst_1
14: invokestatic #3 // Method demoB:(I)V
17: iconst_3
18: invokestatic #3 // Method demoB:(I)V
21: sipush 1024
24: invokestatic #3 // Method demoB:(I)V
27: return
LineNumberTable:
line 5: 0
line 6: 4
line 7: 8
line 8: 13
line 9: 17
line 10: 21
line 11: 27
LocalVariableTable:
Start Length Slot Name Signature
0 28 0 args [Ljava/lang/String;
private static void demoA(boolean);
descriptor: (Z)V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: iload_0
1: ifeq 15
4: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #5 // String This is ture
9: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: goto 23
15: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
18: ldc #7 // String This is false
20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: return
LineNumberTable:
line 14: 0
line 15: 4
line 17: 15
line 19: 23
LocalVariableTable:
Start Length Slot Name Signature
0 24 0 tag Z
StackMapTable: number_of_entries = 2
frame_type = 15 /* same */
frame_type = 7 /* same */
private static void demoB(int);
descriptor: (I)V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: iload_0
1: ifgt 15
4: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #8 // String This is 1
9: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: goto 59
15: iload_0
16: ifle 35
19: iload_0
20: iconst_3
21: if_icmpge 35
24: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
27: ldc #9 // String This is 2
29: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
32: goto 59
35: iload_0
36: iconst_3
37: if_icmpne 51
40: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
43: ldc #10 // String This is 3
45: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
48: goto 59
51: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
54: ldc #11 // String This is something else
56: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
59: return
LineNumberTable:
line 22: 0
line 23: 4
line 24: 15
line 25: 24
line 26: 35
line 27: 40
line 29: 51
line 31: 59
LocalVariableTable:
Start Length Slot Name Signature
0 60 0 num I
StackMapTable: number_of_entries = 4
frame_type = 15 /* same */
frame_type = 19 /* same */
frame_type = 15 /* same */
frame_type = 7 /* same */
}
SourceFile: "ConditionDemo.java"
类加载时执行如下代码:
public org.example.condition.ConditionDemo();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lorg/example/condition/ConditionDemo;
main 方法的字节码如下:
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iconst_1
1: invokestatic #2 // Method demoA:(Z)V
4: iconst_0
5: invokestatic #2 // Method demoA:(Z)V
8: bipush -2
10: invokestatic #3 // Method demoB:(I)V
13: iconst_1
14: invokestatic #3 // Method demoB:(I)V
17: iconst_3
18: invokestatic #3 // Method demoB:(I)V
21: sipush 1024
24: invokestatic #3 // Method demoB:(I)V
27: return
LineNumberTable:
line 5: 0
line 6: 4
line 7: 8
line 8: 13
line 9: 17
line 10: 21
line 11: 27
LocalVariableTable:
Start Length Slot Name Signature
0 28 0 args [Ljava/lang/String;
bool的if else 是简单拆解为 ifeq 和 goto 跳转。 demoA 方法的字节码如下:
private static void demoA(boolean);
descriptor: (Z)V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: iload_0
1: ifeq 15
4: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #5 // String This is ture
9: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: goto 23
15: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
18: ldc #7 // String This is false
20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: return
LineNumberTable:
line 14: 0
line 15: 4
line 17: 15
line 19: 23
LocalVariableTable:
Start Length Slot Name Signature
0 24 0 tag Z
StackMapTable: number_of_entries = 2
frame_type = 15 /* same */
frame_type = 7 /* same */
这里演示一个int的 if, else if, else if, else。 demoB 方法的字节码如下:
private static void demoB(int);
descriptor: (I)V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: iload_0
1: ifgt 15
4: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #8 // String This is 1
9: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: goto 59
15: iload_0
16: ifle 35
19: iload_0
20: iconst_3
21: if_icmpge 35
24: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
27: ldc #9 // String This is 2
29: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
32: goto 59
35: iload_0
36: iconst_3
37: if_icmpne 51
40: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
43: ldc #10 // String This is 3
45: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
48: goto 59
51: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
54: ldc #11 // String This is something else
56: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
59: return
LineNumberTable:
line 22: 0
line 23: 4
line 24: 15
line 25: 24
line 26: 35
line 27: 40
line 29: 51
line 31: 59
LocalVariableTable:
Start Length Slot Name Signature
0 60 0 num I
StackMapTable: number_of_entries = 4
frame_type = 15 /* same */
frame_type = 19 /* same */
frame_type = 15 /* same */
frame_type = 7 /* same */