String、StringBuilder、StringBuffer

17 阅读3分钟

一.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”。

  1. StringBuffer和StringBuilder与String相比,他们的类的对象可以多次被修改,并且不会产生新的变量,即都是同一个变量。

  2. 因此若遇见需要多次被修改的字符串变量的时候,就需要考虑使用StringBuffer和StringBuilder。

  3. StringBuffer和StringBuilder相比较,StringBuffer是线程安全的但是速度慢,StringBuilder是非线程安全的(不能同步访问)但速度快。

  4. 大多数情况下还是使用StringBuilder,若要求必须是线程安全的,则必须使用StringBuffer

三.区别

  1. 字符修改上

    StringStringBuilderStringBuffer
    字符序列不可变可变字符序列可变字符序列
    线程不安全线程安全
    单线程操作字符串多线程操作字符串
  2. 初始化上

    String str=null;

    String s=abc;

    StringBuffer str=null;//警告,不能赋空值

    StringBuffer str=new StringBuffer(); //StringBuffer对象是一个空对象

    StringBuffer s=new String Buffer("ABC");//创建带有内容的StringBuffer对象,对象的内容就是ABC