Java 字节码之解析一
?
例子:一个Java类 TestString.java
Compiled from "TestString.java"public class TestString extends java.lang.Object{public TestString(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return public java.lang.String testString(java.lang.String, java.lang.String); Code: 0: new #16; //class java/lang/StringBuilder 3: dup 4: aload_1 5: invokestatic #18; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 8: invokespecial #24; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 11: aload_2 12: invokevirtual #27; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: invokevirtual #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 18: areturn public java.lang.String testStringBuffer(java.lang.StringBuffer, java.lang.String); Code: 0: aload_1 1: aload_2 2: invokevirtual #40; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer; 5: invokevirtual #45; //Method java/lang/StringBuffer.toString:()Ljava/lang/String; 8: areturn } ?从上面编译后的字节码信息可以看出来,方法testString 调用了五个方法:new 、invokestatic、invokespecial 和两个invokevirtual ; 而testStringBuffer 方法只调用了两个invokevirtual 方法。第一个方法比第二个方法多做了好多工作,其效率当然是要低的。而且我们从java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
可以看出来其实对于String字符串合并,内部还是转化为StringBuilder的方法调用,这是因为String是长度不可变的,所以不如直接采用StringBuilder(与StringBuffer 长度都是可变的,只不过前者是非线程安全,后者是线程安全)进行字符串合并。
?
?
?