java中字符串相加本质详解
摘要:java中字符串相加本质详解
String s = "a" + "b" + "c";
这里,我们先不考虑"a","b","c"是放置在池中这个问题。
这个"+"操作符,java到底是怎么对待的?
一种说法是"a"是一个字符串对象,+"b"之后,又生成一个字符串对象,大概是"ab",+"c"之后,再生成一个字符串对象,大概是"abc",
然后,把"abc"字符串对象的引用返回给s。这样,在这个过程中,共有6个字符串对象产生,这样效率低,所以应该用StringBuffer实现,
如:
StringBuffer sb = new StringBuffer(100);
sb = sb.append("a").append("b").append("c");
再有一个说法,是java对“+”操作符进行重载,最终以StringBuffer实现以上字符串相加动作。
到底哪个说法对?其实以上的问题,也就是问,java对“+”到底重载成什么样子?
1.使用String + 的方式:
public class Test2 {
public static void main(String[] args) {
String a = "a";
String b = "b";
String c = "c";
String s = a + b + c;
}
}
对应的bytecode为:
public class Test2 extends java.lang.Object{
public Test2();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String a
2: astore_1
3: ldc #3; //String b
5: astore_2
6: ldc #4; //String c
8: astore_3
9: new #5; //class StringBuffer
12: dup
13: invokespecial #6; //Method java/lang/StringBuffer."<init>":()V
16: aload_1
17: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
20: aload_2
21: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
24: aload_3
25: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
28: invokevirtual #8; //Method java/lang/StringBuffer.toString:()Ljava/lan
g/String;
31: astore 4
33: return
}
2.使用StringBuffer.append()的方式:
public class Test3 {
public static void main(String[] args) {
String a = "a";
String b = "b";
String c = "c";
StringBuffer sb = new StringBuffer();
sb.append(a).append(b).append(c);
String s = sb.toString();
}
}
对应的bytecode为:
public class Test3 extends java.lang.Object{
public Test3();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String a
2: astore_1
3: ldc #3; //String b
5: astore_2
6: ldc #4; //String c
8: astore_3
9: new #5; //class StringBuffer
12: dup
13: invokespecial #6; //Method java/lang/StringBuffer."<init>":()V
16: astore 4
18: aload 4
20: aload_1
21: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
24: aload_2
25: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
28: aload_3
29: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
32: pop
33: aload 4
35: invokevirtual #8; //Method java/lang/StringBuffer.toString:()Ljava/lan
g/String;
38: astore 5
40: return
}
看到了么?后者不光不比前者效率高,反而多了一些临时变量的存取
这里,我们先不考虑"a","b","c"是放置在池中这个问题。
这个"+"操作符,java到底是怎么对待的?
一种说法是"a"是一个字符串对象,+"b"之后,又生成一个字符串对象,大概是"ab",+"c"之后,再生成一个字符串对象,大概是"abc",
然后,把"abc"字符串对象的引用返回给s。这样,在这个过程中,共有6个字符串对象产生,这样效率低,所以应该用StringBuffer实现,
如:
StringBuffer sb = new StringBuffer(100);
sb = sb.append("a").append("b").append("c");
再有一个说法,是java对“+”操作符进行重载,最终以StringBuffer实现以上字符串相加动作。
到底哪个说法对?其实以上的问题,也就是问,java对“+”到底重载成什么样子?
1.使用String + 的方式:
public class Test2 {
public static void main(String[] args) {
String a = "a";
String b = "b";
String c = "c";
String s = a + b + c;
}
}
对应的bytecode为:
public class Test2 extends java.lang.Object{
public Test2();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String a
2: astore_1
3: ldc #3; //String b
5: astore_2
6: ldc #4; //String c
8: astore_3
9: new #5; //class StringBuffer
12: dup
13: invokespecial #6; //Method java/lang/StringBuffer."<init>":()V
16: aload_1
17: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
20: aload_2
21: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
24: aload_3
25: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
28: invokevirtual #8; //Method java/lang/StringBuffer.toString:()Ljava/lan
g/String;
31: astore 4
33: return
}
2.使用StringBuffer.append()的方式:
public class Test3 {
public static void main(String[] args) {
String a = "a";
String b = "b";
String c = "c";
StringBuffer sb = new StringBuffer();
sb.append(a).append(b).append(c);
String s = sb.toString();
}
}
对应的bytecode为:
public class Test3 extends java.lang.Object{
public Test3();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String a
2: astore_1
3: ldc #3; //String b
5: astore_2
6: ldc #4; //String c
8: astore_3
9: new #5; //class StringBuffer
12: dup
13: invokespecial #6; //Method java/lang/StringBuffer."<init>":()V
16: astore 4
18: aload 4
20: aload_1
21: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
24: aload_2
25: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
28: aload_3
29: invokevirtual #7; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
32: pop
33: aload 4
35: invokevirtual #8; //Method java/lang/StringBuffer.toString:()Ljava/lan
g/String;
38: astore 5
40: return
}
看到了么?后者不光不比前者效率高,反而多了一些临时变量的存取
相关文章
最新发布
阅读排行
热门文章
猜你喜欢