直接上API doc

java.lang.String

The String class represents character strings. All string literals(字面量) in Java programs, such as "abc", are implemented as instances of this class.(所以字符串常量池中存的应该是对象吧?挖坑,后面填)

Strings are constant; their values cannot be changed after they are created. String buffers support mutable (可变的)strings. Because String objects are immutable they can be shared.

The Java language provides special support for the string concatenation operator ( + )【Java语言为字符串连接操作符提供了特殊的支持。, and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java. 

A String represents a string in the UTF-16 format in which supplementary characters are represented by surrogate pairs .

java.lang.StringBuffer

A thread-safe, mutable sequence of characters. A string buffer is like a 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.

String buffers are safe for use by multiple threads. The methods are synchronized where necessary so that all the operations on any particular instance behave as if they occur in some serial order that is consistent with the order of the method calls made by each of the individual threads involved.

java.lang.StringBuilder

A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

 

回答

String 是 Java 语言非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑。它是典型的 Immutable 类被声明成为 final class,所有属性也都是 final 的。也由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的 String 对象(中间对象是StringBuffer,然后调用它的toString方法,new一个String对象出来)。由于字符串操作的普遍性,所以相关操作的效率往往对应用性能有明显影响。

 

StringBuffer 是为解决上面提到拼接产生太多中间对象的问题而提供的一个类,它是 Java 1.5中新增的,我们可以用 append 或者 add 方法,把字符串添加到已有序列的末尾或者指定位置。StringBuffer 本质是一个线程安全的可修改字符序列,它保证了线程安全(因为对类中的操作方法【构造函数没有】加了synchronized关键字),也随之带来了额外的性能开销,所以除非有线程安全的需要,不然还是推荐使用它的后继者,也就是StringBuilder。

 

StringBuilder 在能力上和 StringBuffer 没有本质区别,但是它去掉了线程安全的部分,有效减小了开销,是绝大部分情况下进行字符串拼接的首选。

 

在JDK1.7之后引入了偏向锁,因此StringBuffer和StringBuilder在单线程执行的环境下性能上是差不多的

附加:找一找内部怎么存的,然后不同版本的jdk底层实现的不同

 

附加:StringBuffer和StringBuilder是如何维护它内部的动态char[]的?

    String 类不可变,内部维护的char[] 数组长度不可变,为final修饰,String类也是final修饰,不存在扩容。字符串拼接,截取,都会生成一个新的对象。频繁操作字符串效率低下,因为每次都会生成新的对象。

    StringBuilder 类内部维护可变长度char[] , 初始化数组容量为16,存在扩容, 其append拼接字符串方法内部调用System的native方法,进行数组的拷贝,不会重新生成新的StringBuilder对象。非线程安全的字符串操作类, 其每次调用 toString方法而重新生成的String对象,不会共享StringBuilder对象内部的char[],会进行一次char[]的copy操作。

    StringBuffer 类内部维护可变长度char[], 基本上与StringBuilder一致,但其为线程安全的字符串操作类,大部分方法都采用了Synchronized关键字修改,以此来实现在多线程下的操作字符串的安全性。其toString方法而重新生成的String对象,会共享StringBuffer对象中的toStringCache属性(char[]),但是每次的StringBuffer对象修改,都会置null该属性值。

    源码解析哪天心情好再添加:)可以看零碎小知识的网页剪切。

 

附加:String的+操作在编译器里是如何优化的?

String str = "a" + "b";  优化为ab

String str = "a" + (1 + 2);  优化为a3

注:String相加还可以使用concat

        

String s = "b";  

String str = "a" + s;  

这个是创建一个StringBuilder对象,调用append方法进行添加,调用toString重新生成String对象