字符串常量:String、StringBuffer和StringBuilder的区别?

本文介绍了Java中的String、StringBuffer和StringBuilder的区别。String字符串不可变,频繁拼接会导致内存浪费;而StringBuffer和StringBuilder则支持可变操作,其中StringBuffer是线程安全的,StringBuilder效率更高。在进行大量字符串操作时,推荐使用StringBuilder。文章还详细阐述了字符串常量池的概念和作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

String 字符串

String类 是被 final关键字 声明的,因此它不可被继承。 String 字符串是引用类型,底层用 char 数组实现的。

String 字符串的特点:

        1.字符串不可变,它们的值在创建后不能被更改。

        2.虽然String 的值是不可变的,但是可以被共享 字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )。

String 字符串解析:

        1.通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,即使内容相同,但地址值不同。

        2.以“”方式给出的字符串,JVM会将其存放在 字符串常量池 中维护。

        3.且若多个“”方式给出的字符序列(顺序及大小写)相同,JVM只会建立一个String 对象。

为什么 String 字符串 不适用于 大量 字符串 拼接 操作?

String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,对内存空间的极大浪费。

String 字符串的 + 操作(字符串 拼接 操作)其本质是创建了 StringBuilder 对象进行 append() 操作,然后将拼接后的 StringBuilder 对象用 toString() 方法处理成 String 对象。

在 Java 中无论使用何种方式进行字符串连接,实际上都使用的是 StringBuilder。

我们知道,在Java中有两种创建字符串对象的方式:

  1. 采用字面值的方式赋值。
  2. 采用new关键字 新建一个字符串对象。

String str = new String("abc")创建了几个对象?

创建2个对象。

第一个对象是”abc”字符串 存储 在字符串常量池中;

第二个对象在JAVA Heap堆 中 new 的 String 对象

String str = "a" + "b" + "c" 创建了几个对象?

创建1个对象。

因为 赋值符号右边的"a"、"b"、"c"都是常量

String str = new String("a") + new String("b")创建了几个对象?

创建6个对象。

        对象1:new StringBuilder()

        对象2:new String("a")

        对象3:常量池的 a

        对象4:new String("b")

        对象5:常量池的 b

        对象6:toString中会创建一个 new String("ab")

String str= "abc";
final String finalStr = "abc";//final修饰的是常量

String str1 = "abc01";    
        
String str2 = "abc" + "01";    
    
String str3 = str + "01";    
    
String str4 = finalStr + "01";   
 
String str5 = new String("abc01").intern();    


System.out.println(str1 == str2);    // true
System.out.println(str1 == str3);    // false
System.out.println(str1 == str4);    // true   //final修饰的是常量
System.out.println(str1 == str5);    // true

String、StringBuffer 和 StringBuilder 的区别

1)、可变不可变

String:字符串常量,在修改时不会改变自身;若修改,等于重新生成新的字符串对象。
StringBuffer:字符串变量,在修改时会改变对象自身,每次操作都是对 StringBuffer 对象本身进行修改,不是生成新的对象;
使用场景:对字符串经常改变情况下,主要方法:append(),insert()等。

2)、线程是否安全

String:对象定义后不可变,线程安全。
StringBuffer:是线程安全的(对调用方法加入synchronized同步锁),执行效率较慢,适用于多线程下操作字符串缓冲区大量数据。
StringBuilder:是线程不安全的,StringBuilder 效率高于 StringBuffer,适用于单线程下操作字符串缓冲区大量数据。

3)、共同点

StringBuilder 与 StringBuffer 有公共父类 AbstractStringBuilder(抽象类)
StringBuilder、StringBuffer 的方法都会调用 AbstractStringBuilder 中的公共方法,只是StringBuffer 会在方法上加 synchronized 关键字,进行同步。
最后,如果程序不是多线程的,那么使用 StringBuilder 效率高于 StringBuffer。

String

不可变字符串线程安全每次new 都是生成新的String对象不适用于 大量 字符串 拼接 操作,影响内存性能

StringBuffer

可变字符串线程安全StringBuffer 执行效率慢适用于多线程下操作字符串缓冲区大量数据

StringBuilder

可变字符串线程不安全StringBuilder 执行效率高适用于单线程下操作字符串缓冲区大量数据

常量

final修饰的成员变量表示常量,值一旦给定就无法改变!

final修饰的变量分别表示三种类型的常量:静态变量、实例变量 和 局部变量。

Java中的常量池,实际上分为两种形态:静态常量池 和 运行时常量池

    1)静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。

    2)运行时常量池,则是JVM虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。

常量池(Constant Pool)

常量池,也叫 Class 常量池(常量池==Class常量池,Class Constant Pool)。Java文件被编译成 Class文件,Class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项就是常量池,每个class文件都有一个class常量池。常量池是当Class文件被Java虚拟机加载进来后存放在方法区 各种 字面量 (Literal)符号引用(SymbolicReferences)

字面量 包括:1.文本字符串 2.八种基本类型的值 3.被声明为final的常量等;

符号引用 包括:1.类和方法的全限定名 2.字段的名称和描述符 3.方法的名称和描述符。

运行时常量池(Runtime Constant Pool)

运行时常量池是方法区的一部分。运行时常量池是当Class文件被加载到内存后,Java虚拟机会 将Class文件常量池里的内容转移到运行时常量池里(运行时常量池也是每个类都有一个)。运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中

字符串常量池(String Constant Pool)

字符串常量池又称为:字符串池,全局字符串池,英文也叫String Constant Pool。

字符串常量池是全局的,JVM中独此一份,因此也称为全局字符串常量池

String的String Pool是一个固定大小的Hashtable,默认值大小长度是1009。

在工作中,String类是我们使用频率非常高的一种对象类型。JVM为了提升性能和减少内存开销,避免字符串的重复创建,其维护了一块特殊的内存空间,这就是我们今天要讨论的核心:字符串常量池。字符串常量池由String类私有的维护

class常量池 是在编译的时候每个class都有的. 在编译阶段,存放的是常量的 符号引用 。       [在class文件中]


字符串常量池 在每个VM中只有一份,存放的是字符串常量的 引用值 。  [在堆中]              


运行时常量池 是在类加载完成之后,将每个class常量池 中的符号引用值转存到 运行时常量池 中,也就是说,每个class都有一个 运行时常量池 ,类在 解析阶段 ,将 符号引用 替换成 直接引用 ,与 字符串常量池 中的引用值保持一致。[在方法区]  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值