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类。

相关文章
|
3天前
|
Java 索引
String字符串常用函数以及示例 JAVA基础
String字符串常用函数以及示例 JAVA基础
|
3天前
|
存储 安全 Java
Java中的这些String特性可能需要了解下
Java中的String特性你知道哪些?虽然String很常见,通过源码可以看到String的值传递、字符串表和不可变性。本文基于JDK17说明。
9 1
|
3天前
|
存储 Java
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
|
4天前
|
Java
Java String 避免空指针的方法
Java String 避免空指针的方法
5 0
|
5天前
|
Java 编译器 ice
【Java开发指南 | 第十五篇】Java Character 类、String 类
【Java开发指南 | 第十五篇】Java Character 类、String 类
24 1
|
5天前
|
Java API 索引
Java基础—笔记—String篇
本文介绍了Java中的`String`类、包的管理和API文档的使用。包用于分类管理Java程序,同包下类无需导包,不同包需导入。使用API时,可按类名搜索、查看包、介绍、构造器和方法。方法命名能暗示其功能,注意参数和返回值。`String`创建有两种方式:双引号创建(常量池,共享)和构造器`new`(每次新建对象)。此外,列举了`String`的常用方法,如`length()`、`charAt()`、`equals()`、`substring()`等。
16 0
|
5天前
|
缓存 Java
Java中循环创建String对象的内存管理分析
Java中循环创建String对象的内存管理分析
29 2
|
5天前
|
存储 缓存 安全
【 Java中String源码分析(JVM视角你不来看看?】
【 Java中String源码分析(JVM视角你不来看看?】
14 0
|
5天前
|
Java
Java String类型转换成Date日期类型
Java String类型转换成Date日期类型
|
5天前
|
Java 索引
Java String应用与开发
Java String应用与开发
22 0