我们在写字符处理的时候总会因为各种原因是用“+”符号拼接如:
public String say(String firstName,String lastName){
String outStr="my first name "+firstName+",last name "+lastName;
return outStr;
}
或者如下:
public class Test { String str1 = "one"; String str2 = "two"; String str3 = str1 + str2; public static void main(String[] args) { Test test=new Test(); System.out.println(test); } }然后通过java命令打印编译后的代码如下:
PS D:\test\untitled\out\production\untitled> javap -v .\Test.class
Classfile /D:/test/untitled/out/production/untitled/Test.class
Last modified 2018-5-14; size 842 bytes
MD5 checksum 5712b8484d1204231aa98da61f083883
Compiled from "Test.java"
public class Test
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #15.#34 // java/lang/Object."<init>":()V
#2 = String #35 // one
#3 = Fieldref #11.#36 // Test.str1:Ljava/lang/String;
#4 = String #37 // two
#5 = Fieldref #11.#38 // Test.str2:Ljava/lang/String;
#6 = Class #39 // java/lang/StringBuilder
#7 = Methodref #6.#34 // java/lang/StringBuilder."<init>":()V
#8 = Methodref #6.#40 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#9 = Methodref #6.#41 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#10 = Fieldref #11.#42 // Test.str3:Ljava/lang/String;
#11 = Class #43 // Test
#12 = Methodref #11.#34 // Test."<init>":()V
#13 = Fieldref #44.#45 // java/lang/System.out:Ljava/io/PrintStream;
#14 = Methodref #46.#47 // java/io/PrintStream.println:(Ljava/lang/Object;)V
#15 = Class #48 // java/lang/Object
#16 = Utf8 str1
#17 = Utf8 Ljava/lang/String;
#18 = Utf8 str2
#19 = Utf8 str3
#20 = Utf8 <init>
#21 = Utf8 ()V
#22 = Utf8 Code
#23 = Utf8 LineNumberTable
#24 = Utf8 LocalVariableTable
#25 = Utf8 this
#26 = Utf8 LTest;
#27 = Utf8 main
#28 = Utf8 ([Ljava/lang/String;)V
#29 = Utf8 args
#30 = Utf8 [Ljava/lang/String;
#31 = Utf8 test
#32 = Utf8 SourceFile
#33 = Utf8 Test.java
#34 = NameAndType #20:#21 // "<init>":()V
#35 = Utf8 one
#36 = NameAndType #16:#17 // str1:Ljava/lang/String;
#37 = Utf8 two
#38 = NameAndType #18:#17 // str2:Ljava/lang/String;
#39 = Utf8 java/lang/StringBuilder
#40 = NameAndType #49:#50 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#41 = NameAndType #51:#52 // toString:()Ljava/lang/String;
#42 = NameAndType #19:#17 // str3:Ljava/lang/String;
#43 = Utf8 Test
#44 = Class #53 // java/lang/System
#45 = NameAndType #54:#55 // out:Ljava/io/PrintStream;
#46 = Class #56 // java/io/PrintStream
#47 = NameAndType #57:#58 // println:(Ljava/lang/Object;)V
#48 = Utf8 java/lang/Object
#49 = Utf8 append
#50 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#51 = Utf8 toString
#52 = Utf8 ()Ljava/lang/String;
#53 = Utf8 java/lang/System
#54 = Utf8 out
#55 = Utf8 Ljava/io/PrintStream;
#56 = Utf8 java/io/PrintStream
#57 = Utf8 println
#58 = Utf8 (Ljava/lang/Object;)V
{
java.lang.String str1;
descriptor: Ljava/lang/String;
flags:
java.lang.String str2;
descriptor: Ljava/lang/String;
flags:
java.lang.String str3;
descriptor: Ljava/lang/String;
flags:
public Test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2 // String one
7: putfield #3 // Field str1:Ljava/lang/String;
10: aload_0
11: ldc #4 // String two
13: putfield #5 // Field str2:Ljava/lang/String;
16: aload_0
17: new #6 // class java/lang/StringBuilder
20: dup
21: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
24: aload_0
25: getfield #3 // Field str1:Ljava/lang/String;
28: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
31: aload_0
32: getfield #5 // Field str2:Ljava/lang/String;
35: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
38: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
41: putfield #10 // Field str3:Ljava/lang/String;
44: return
LineNumberTable:
line 1: 0
line 2: 4
line 3: 10
line 4: 16
LocalVariableTable:
Start Length Slot Name Signature
0 45 0 this LTest;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: new #11 // class Test
3: dup
4: invokespecial #12 // Method "<init>":()V
7: astore_1
8: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream;
11: aload_1
12: invokevirtual #14 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
15: return
LineNumberTable:
line 7: 0
line 8: 8
line 9: 15
LocalVariableTable:
Start Length Slot Name Signature
0 16 0 args [Ljava/lang/String;
8 8 1 test LTest;
}
SourceFile: "Test.java"
仔细看看再加上八九不离十,没有使用StringBuild 任何申明,编译之后却有出现。
那么问题就来了,竟然编译之后是Stringbuild那么为什么不直接使用stringbuild的呢?
你可以做一个小小的测试:测试思虑是:
循环10000个字符拼接和Stringbuild.append()做一下时间比较你就知道了。你怎么做才是正确。
最后的结果当然是Stringbuild.append()比较好
优点:
1、不需要编译器再次编译成Stringbuild.append()
2、减少资源浪费(每次字符拼接的是时候都需要new Stringbuild然后把旧的拷贝新Stringbuild里再tostring赋值给变量)
3、代码可读性高。