一.String
String是一个类,通过String定义的变量是引用类型。
String是不可变的对象,因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String 。
栈内存 | 堆内存 | |
---|---|---|
str | “hello” | String str=“hello”; |
“world” | world要另外开辟堆内存 | |
“hello world” | str+“world” |
这里 str=str+“world” 改变的是堆内存的地址的指向,指向“hello world”。初始String值为“hello”,然后在这个字符串后面加上新的字符串“world”,这个过程是需要重新在栈堆内存中开辟内存空间的,最终得到了“hello world”字符串也相应的需要开辟内存空间,这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费。为了应对经常性的字符串相关的操作,就需要使用Java提供的其他两个操作字符串的类——StringBuffer类和StringBuild类来对此种变化字符串进行处理。
二.StringBuffer和StringBuilder
StringBuilder是一个可变的字符序列,是5.0新增的。此类提供一个与StringBuffer兼容的API,但不能保持同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
StringBuffer是线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。str.append("world"),则 str=“helloWorld”,会使字符串缓冲区包含“helloworld”;而 str.insert(1, "world") 将更改字符串缓冲区,使之包含“hworldello”。
-
StringBuffer和StringBuilder与String相比,他们的类的对象可以多次被修改,并且不会产生新的变量,即都是同一个变量。
-
因此若遇见需要多次被修改的字符串变量的时候,就需要考虑使用StringBuffer和StringBuilder。
-
StringBuffer和StringBuilder相比较,StringBuffer是线程安全的但是速度慢,StringBuilder是非线程安全的(不能同步访问)但速度快。
-
大多数情况下还是使用StringBuilder,若要求必须是线程安全的,则必须使用StringBuffer
三.区别
-
字符修改上
String StringBuilder StringBuffer 字符序列不可变 可变字符序列 可变字符序列 线程不安全 线程安全 单线程操作字符串 多线程操作字符串 -
初始化上
String str=null;
String s=abc;
StringBuffer str=null;//警告,不能赋空值
StringBuffer str=new StringBuffer(); //StringBuffer对象是一个空对象
StringBuffer s=new String Buffer("ABC");//创建带有内容的StringBuffer对象,对象的内容就是ABC