Java中String、StringBuilder和StringBuffer的区别

简介: Java中String、StringBuilder和StringBuffer的区别

一.String类

String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。

字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:

String str = "abc";

等效于:

char[] data = {'a','b','c'};
     String str = new String(data);

Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中的所有类继承

因此,str += "here"; 等同于:

StringBuilder sb = new StringBuilder(str);
     sb.append("here");
     str = sb.toString();

可见对字符串相加时先要创建StringBuilder对象,然后append,最后toString(),效率比直接使用StringBuilder(或StringBuffer)的append()要低得多,因此在对字符串进行拼接时提倡使用StringBuilder(或StringBuffer),而不是字符串直接相加。

接下来再讨论构造方法: public String(String original),初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。由于 String 是不可变的,所以无需使用此构造方法,除非需要 original 的显式副本。

所以对于String str = new String("here"); 编译器先在String pool中检查是否有内容为"here”的字符串,如果Sting pool中已经存在字符串"here",则程序通过new String("here")在堆中创建一个字符串"here",如果Sting pool中没有"here",则执行这句的时候在String pool和堆中分别创建一个对象,对象的内容为字符串"here",str指向堆中"here"的引用。

很显然,一般情况下我们直接使用String str = "here"; 即可,不通过构造方法。

二.StringBuffer类

StringBuffer是线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。

可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

例如,如果 z 引用一个当前内容为 "start" 的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含 "startle",而 z.insert(4, "le") 将更改字符串缓冲区,使之包含 "starlet"。

通常,如果 sb 引用 StringBuilder 的一个实例,则 sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果。

当发生与源序列有关的操作(如源序列中的追加或插入操作)时,该类只在执行此操作的字符串缓冲区上而不是在源上实现同步。

每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。

StringBuffer是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象,而且它只能通过构造函数来建立:

StringBuffer sb = new StringBuffer();

注意:不能通过赋值符号对他进行赋值.

sb = "welcome to here!";   //error

对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.字符串连接操作中StringBuffer的效率要比String高出许多。

三.StringBuilder类

StringBuilder类是从 JDK 5 开始新增的,此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。与StringBuffer类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。如果可能,建议优先采用该类,因为在大多数情况中,它比 StringBuffer 要快。

注意:将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer类。

相关文章
|
2月前
|
Java 程序员 调度
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
77 9
|
2月前
|
安全 Java 程序员
Java面试必问!run() 和 start() 方法到底有啥区别?
在多线程编程中,run和 start方法常常让开发者感到困惑。为什么调用 start 才能启动线程,而直接调用 run只是普通方法调用?这篇文章将通过一个简单的例子,详细解析这两者的区别,帮助你在面试中脱颖而出,理解多线程背后的机制和原理。
73 12
|
3月前
|
Java
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
今日分享的主题是如何区分&和&&的区别,提高自身面试的能力。主要分为以下四部分。 1、自我面试经历 2、&amp和&amp&amp的不同之处 3、&对&&的不同用回答逻辑解释 4、彩蛋
|
4月前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
112 14
|
3月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
41 1
|
4月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
122 8
|
4月前
|
安全
String、StringBuffer、StringBuilder的区别
String 由 char[] 数组构成,使用了 final 修饰,对 String 进行改变时每次都会新生成一个 String 对象,然后把指针指向新的引用对象。 StringBuffer可变并且线程安全;有一定缓冲区容量,字符串大小没超过容量,不会重新分配新的容量,适合多线程操作字符串; StringBuiler可变并且线程不安全。速度比StringBuffer更快,适合单线程操作字符串。 操作少量字符数据用 String;单线程操作大量数据用 StringBuilder;多线程操作大量数据用 StringBuffer
|
1天前
|
Java
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、"+"操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
|
1天前
|
存储 JavaScript Java
课时44:String类对象两种实例化方式比较
本次课程的主要讨论了两种处理模式在Java程序中的应用,直接赋值和构造方法实例化。此外,还讨论了字符串池的概念,指出在Java程序的底层,DOM提供了专门的字符串池,用于存储和查找字符串。 1.直接赋值的对象化模式 2.字符串池的概念 3.构造方法实例化
|
4月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
117 2