---- 待完善............................
1. java代码
public class Test2 {
public void testString() {
String a = "hello";
String b = "word";
String c = a + b;
System.out.println(c);
}
public void testString2() {
String c = "";
for(int i=0;i<10;i++) {
c = c+i;
}
System.out.println(c);
}
public void testStringBuffer() {
String a = "hello";
String b = "word";
StringBuffer c = new StringBuffer("");
c.append(a).append(b);
System.out.println(c);
}
public void testStringBuffer2() {
StringBuffer c = new StringBuffer("");
for(int i=0;i<10;i++) {
c = c.append(i);
}
System.out.println(c);
}
}
2. 字节码
Compiled from "Test2.java"
public class com.java.test.Test2 extends java.lang.Object{
public com.java.test.Test2();
Code:
0: aload_0
-- 将第一个引用类型本地变量推送至栈顶
1: invokespecial #9; //Method java/lang/Object."<init>":()V
-- 调用超类构造方法,实例初始化方法,私有方法
4: return
-- 从当前方法返回void
public void testString();
Code:
0: ldc #16; //String hello
-- 将int, float或String型常量值从常量池中推送至栈顶
2: astore_1
-- 将栈顶引用型数值存入第二个本地变量
3: ldc #18; //String word
5: astore_2
6: new #20; //class java/lang/StringBuilder
-- 创建一个新的对象,并将其引用值压入栈顶。 #20是常量池索引(本类其它和String有关的new这个值都是一样的)。
-- 表示常量池中第20个索引的值。class java/lang/StringBuilder,该指令占用3个字节。
9: dup
-- 复制栈顶数值并将复制值压入栈顶
--JVM新创建一个对象后,首先需要调用<init>实例初始化方法,
--初始化完成后再会做保存到局部变量或调用方法的处理(类似代码:Object obj = new Object();),
--这样就需要在操作数栈上保留两个相同的对象引用,所以需要dup。
10: aload_1
-- 将第二个引用类型本地变量推送至栈顶
11: invokestatic #26; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
-- 调用静态方法 String.valueOf
14: invokespecial #29; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
-- 调用超类构造方法,实例初始化方法,私有方法 调用StringBuilder的init方法
17: aload_2
-- 将第三个引用类型本地变量推送至栈顶
18: invokevirtual #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
-- 调用实例方法,调用StringBuilder.append
21: invokevirtual #37; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
-- 调用实例方法,调用StringBuilder.toString
24: astore_3
-- 将栈顶引用型 数值存入第四个本地变量
25: getstatic #43; //Field java/lang/System.out:Ljava/io/PrintStream;
-- 获取指定类的静态域,并将其值压入栈顶
28: aload_3
-- 将第四个引用类型本地变量推送至栈顶
29: invokevirtual #48; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
-- 调用实例方法 println PrintStream.println
32: return
public void testString2();
Code:
0: ldc #55; //String
-- 将int, float或String型常量值从常量池中推送至栈顶
2: astore_1
3: iconst_0
4: istore_2
5: goto 30
-- 无条件跳转 即跳转到 30: iload_2 这里
8: new #20; //class java/lang/StringBuilder
11: dup
12: aload_1
13: invokestatic #26; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
16: invokespecial #29; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
19: iload_2
20: invokevirtual #58; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
23: invokevirtual #37; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
26: astore_1
27: iinc 2, 1
--将指定int型变量增加指定值(i++, i--, i+=2)
30: iload_2
--将第三个int型本地变量推送至栈顶
31: bipush 10
--将单字节的常量值(-128~127)推送至栈顶
33: if_icmplt 8
--比较栈顶两int型数值大小,当结果小于0时跳转
36: getstatic #43; //Field java/lang/System.out:Ljava/io/PrintStream;
39: aload_1
40: invokevirtual #48; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
43: return
public void testStringBuffer();
Code:
0: ldc #16; //String hello
2: astore_1
3: ldc #18; //String word
5: astore_2
6: new #63; //class java/lang/StringBuffer
9: dup
10: ldc #55; //String
12: invokespecial #64; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
15: astore_3
16: aload_3
17: aload_1
18: invokevirtual #67; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
21: aload_2
22: invokevirtual #67; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
25: pop
--将栈顶数值弹出 (数值不能是long或double类型的)
26: getstatic #43; //Field java/lang/System.out:Ljava/io/PrintStream;
29: aload_3
30: invokevirtual #70; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
33: return
public void testStringBuffer2();
Code:
0: new #63; //class java/lang/StringBuffer
3: dup
4: ldc #55; //String
6: invokespecial #64; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
9: astore_1
10: iconst_0
11: istore_2
12: goto 24
15: aload_1
16: iload_2
17: invokevirtual #75; //Method java/lang/StringBuffer.append:(I)Ljava/lang/StringBuffer;
20: astore_1
21: iinc 2, 1
-- iinc index ,const
-- The index is an unsigned byte that must be an index into the local variable array of
-- the current frame . The const is an immediate signed byte. The local variable
-- at index must contain an int. The value const is first sign-extended to an int, and
-- then the local variable at index is incremented by that amount.
24: iload_2
25: bipush 10
27: if_icmplt 15
30: getstatic #43; //Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: invokevirtual #70; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
37: return
}