标签:
public class Concatenation {
public static void main(String[] args) {
String mango = "mango";
String s = "abc" + mango + "def" + 47;
System.out.println(s);
}
} /* Output:
abcmangodef47
*///:~
引入一段代码,大家都知道“+”与“+=”操作符是java中仅有的两个重载过的操作符(java并不允许程序员重载任何操作符),“+”可以用来连接String,如上述代码所示。
可能大家都知道这段代码是怎么工作的,按照编程思想书中的描述,可以用JDK自带的工具javap来反编译上述代码,命令如下:javap -c Concatenation 这里的“-c”表示将生成JVM代码。我跑了一下结果如下:
public class Concatenation {
public Concatenation();
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 mango
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<
init>":()V
10: ldc #5 // String abc
12: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7 // String def
21: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: bipush 47
26: invokevirtual #8 // Method java/lang/StringBuilder.ap
pend:(I)Ljava/lang/StringBuilder;
29: invokevirtual #9 // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
32: astore_2
33: getstatic #10 // Field java/lang/System.out:Ljava/
io/PrintStream;
36: aload_2
37: invokevirtual #11 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
40: return
}
据说有汇编语言经验的看着会觉得眼熟,这里的重点就是编译器自动引入了java.lang.StringBuilder类,虽然源码并没有使用StringBuilder类,但是编译器自作主张地使用了它,因为它更高效。
StringBuilder是java SE5引入的,如果看源码会注意到这样一段注释
* @author Michael McCloskey * @see java.lang.StringBuffer * @see java.lang.String * @since 1.5 */ public final class StringBuilder
since 1.5,那么在这之前java用的是什么呢,就是StringBuffer。
* @author Arthur van Hoff * @see java.lang.StringBuilder * @see java.lang.String * @since JDK1.0 */ public final class StringBuffer
1.0就已经有了,而且是线程安全的,因此开销也会大些,所以在java SE5/6中(现在已经到8了),字符串的操作应该还会更快一些。
看过源码就会发现,注释的第一句话就对线程是否安全做了说明
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package java.lang;
import java.util.Arrays;
/**
* A thread-safe, mutable sequence of characters.
* A string buffer is like a {@link String}, but can be modified. At any
* point in time it contains some particular sequence of characters, but
* the length and content of the sequence can be changed through certain
* method calls.
看看源码就会发现,StringBuffer类的很多方法都是用了synchronized关键字声明,而StringBuilder并没有,StringBuilder属于非线程安全。
StringBuffer和StringBuilder的父类都是AbstractStringBuilder,他们的构造方法都是调用父类的构造方法
/**
* Constructs a string buffer with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuffer() {
super(16);
}
/**
* Constructs a string builder with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuilder() {
super(16);
}
/**
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
String Buffer 和 String Build学习笔记
标签:
原文地址:http://my.oschina.net/weaver/blog/512294