java基础之string字节码初步
java基础之string字节码初始
---- 待完善............................
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 }