String
在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。
String 类是不可变类,即当一个 String 变量被创建时,它将被存储在 Constant String Pool 中。
String之所以是不可变量,是因为,该类被 fainal 修饰
在 Java 中,每一个非易失的变量都是线程安全的,因此 String 变量也是线程安全的。String 变量是不能被两个线程同时拥有的,并且一旦被赋值便不能被修改。
String demo = "hello";
上面这个对象被存储在Constant String Pool当中,它的值不能被改变
demo = "Bye"; // 新的字符串变量"Bye"在Constant String Pool中被创建,但仍然被demo引用
而String "hello"仍然存在于Constant String Pool中,它的值并没有被重写,只不过并没有任何变量费用它
StringBuffer&StringBuilder
Java 提供了两个可变字符串类 StringBuffer 和 StringBuilder,中文翻译为“字符串缓冲区”。两者的对象都是创建在堆上,并且其值可以修改
因为两者继承的同一个接口AbstractStringBuilder,所以拥有相同的方法。
两者不同点在于StringBuffer上每个方法都是使用 synchronized 来修饰的,因此 StringBuffer 是线程安全的。而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用 StringBuilder 类。
StringBuffer、StringBuilder、String 中都实现了 CharSequence 接口。CharSequence 是一个定义字符串操作的接口,它只包括 length()、charAt(int index)、subSequence(int start, int end) 这几个 API。
StringBuffer、StringBuilder、String 对 CharSequence 接口的实现过程不一样,如下图所示:
可见,String 直接实现了 CharSequence 接口,StringBuilder 和 StringBuffer 都是可变的字符序列,它们都继承于 AbstractStringBuilder,实现了 CharSequence 接口。
总结
String 是 Java 中基础且重要的类,被声明为 final class,是不可变字符串。因为它的不可变性,所以拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所影响。
StringBuffer 就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类。它提供了 append 和 add 方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列。
在很多情况下我们的字符串拼接操作不需要线程安全,所以 StringBuilder 登场了。StringBuilder 是 JDK1.5 发布的,它和 StringBuffer 本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。
线程安全:
StringBuffer:线程安全
StringBuilder:线程不安全
速度:
一般情况下,速度从快到慢为 StringBuilder > StringBuffer > String,当然这是相对的,不是绝对的。
使用环境:
操作少量的数据使用 String。
单线程操作大量数据使用 StringBuilder。
多线程操作大量数据使用 StringBuffer。