public static void test(){
String a = "x"+"y"+"1";
String b = "xy1";
System.out.println(a == b);
}
public class test.Test8
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Class #2 // test/Test8
#2 = Utf8 test/Test8
#3 = Class #4 // java/lang/Object
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Methodref #3.#9 // java/lang/Object."<init>":()V
#9 = NameAndType #5:#6 // "<init>":()V
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Ltest/Test8;
#14 = Utf8 test
#15 = String #16 // xy1
#16 = Utf8 xy1
#17 = Fieldref #18.#20 // java/lang/System.out:Ljava/io/PrintStream;
#18 = Class #19 // java/lang/System
#19 = Utf8 java/lang/System
#20 = NameAndType #21:#22 // out:Ljava/io/PrintStream;
#21 = Utf8 out
#22 = Utf8 Ljava/io/PrintStream;
#23 = Methodref #24.#26 // java/io/PrintStream.println:(Z)V
#24 = Class #25 // java/io/PrintStream
#25 = Utf8 java/io/PrintStream
#26 = NameAndType #27:#28 // println:(Z)V
#27 = Utf8 println
#28 = Utf8 (Z)V
#29 = Utf8 a
#30 = Utf8 Ljava/lang/String;
#31 = Utf8 b
#32 = Utf8 StackMapTable
#33 = Class #34 // java/lang/String
#34 = Utf8 java/lang/String
#35 = Utf8 SourceFile
#36 = Utf8 Test8.java
{
public test.Test8();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable: // 代码行数 对应的字节码序号
line 3: 0 // 源文件第三行代码对应第0个字节码序号
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Ltest/Test8;
public static void test();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=0 // stack=3代表本地栈的slot个数为3,俩个String需要load,System的out也会占用一个,当发生对比生成boolean的时候,会将俩个String的引用从栈顶pop出来,所以最多是3个slot。Locals为2,因为只有俩个String,如果是非静态方法,则本地变量会自动增加this。
0: ldc #15 // String xy1
2: astore_0
3: ldc #15 // String xy1
5: astore_1
6: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_0
10: aload_1
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #23 // Method java/io/PrintStream.println:(Z)V
22: return
LineNumberTable:
line 5: 0
line 6: 3
line 7: 6
line 8: 22
LocalVariableTable:
Start Length Slot Name Signature
3 20 0 a Ljava/lang/String; // 第一个本地变量的作用区域从第三个字节的位置开始,作用区域范围为20个字节,所在slot的位置是第0个位置,名称为a,类型为java.lang.String
6 17 1 b Ljava/lang/String;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 18
locals = [ class java/lang/String, class java/lang/String ]
stack = [ class java/io/PrintStream ]
frame_type = 255 /* full_frame */
offset_delta = 0
locals = [ class java/lang/String, class java/lang/String ]
stack = [ class java/io/PrintStream, int ]
}
Stack代表栈顶的单位大小(每个大小为1个slot,每个slot是4个字节的宽度),这里的栈的宽度为1,代表有一个this将会被使用。
Locals代表本地变量的slot个数,代表本地变量在这个方法生命周期内,局部变量最多的时候,需要多大的宽度来存放数据(double、long会占用俩个slot)。
args_size代表的是入口参数个数。
invokespecial #1;//Method java/lang/Object."<init>":()V
当发生构造方法调用、父类的构造方法调用、非静态的private方法调用时会使用该指令,这里需要从常量池中获取一个方法,这个地方会占用2个字节的宽度。
jvm指令官方文档:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-7.html
以上内容摘自《Java特种兵》 作者:谢宇
2.摘自《Java特种兵》 作者:谢宇
public static void test(){
int a=1,b=1,c=1,d=1;
a++;
++b;
c = c++;
d = ++d; // The assignment to variable d has no effect
// System.out.println(a +b + c + d); // 2,2,1,2
}
public class test.Test8
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Class #2 // test/Test8
#2 = Utf8 test/Test8
#3 = Class #4 // java/lang/Object
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Methodref #3.#9 // java/lang/Object."<init>":()V
#9 = NameAndType #5:#6 // "<init>":()V
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Ltest/Test8;
#14 = Utf8 test
#15 = Utf8 a
#16 = Utf8 I
#17 = Utf8 b
#18 = Utf8 c
#19 = Utf8 d
#20 = Utf8 SourceFile
#21 = Utf8 Test8.java
{
public test.Test8();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Ltest/Test8;
public static void test();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=4, args_size=0
0: iconst_1
1: istore_0
2: iconst_1
3: istore_1
4: iconst_1
5: istore_2
6: iconst_1
7: istore_3
8: iinc 0, 1
11: iinc 1, 1
14: iload_2
15: iinc 2, 1
18: istore_2
19: iinc 3, 1
22: iload_3
23: istore_3
24: return
LineNumberTable:
line 5: 0 // 对应 int a=1,b=1,c=1,d=1;
line 7: 8 // 对应 a++;
line 8: 11 // 对应 ++b;
line 9: 14 // c = c++;
line 10: 19 // d = ++d;
line 12: 24
LocalVariableTable:
Start Length Slot Name Signature
2 23 0 a I
4 21 1 b I
6 19 2 c I
8 17 3 d I
}
3.
public static void test(){
int i = 0;
int x = (i++) + (++i) + (i++);
}
public static void test();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=0
0: iconst_0
1: istore_0
2: iload_0
3: iinc 0, 1
6: iinc 0, 1
9: iload_0
10: iadd
11: iload_0
12: iinc 0, 1
15: iadd
16: istore_1
17: return
LineNumberTable:
line 5: 0
line 6: 2
line 7: 17
LocalVariableTable:
Start Length Slot Name Signature
2 16 0 i I
17 1 1 x I