0
点赞
收藏
分享

微信扫一扫

浅谈String、StringBuffer与StringBuilder

49路末班车 2022-03-25 阅读 98
java

String、StringBuffer与StringBuilder

String

String 类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。

例如:

String a = "123";
a = "456";

System.out.println(a)	// 打印出来的a为456

咦,这不是明明已经对他进行修改了吗?为什么还说他是一个不可变类呢?接下来就看一张上述a对象的内存存储空间图

在这里插入图片描述

可以看出,再次给a赋值时,并不是对原来堆中实例对象进行重新赋值,而是生成一个新的实例对象,并且指向“456”这个字符串,a则指向最新生成的实例对象,之前的实例对象仍然存在,如果没有被再次引用,则会被垃圾回收。


String实例化的两种方式

  1. 通过字面量方式实例化
String str = "abc";
  1. 通过new+构造器的方式实例化
String str=new String("abc");
  1. 区别:
    通过字面量方式为字符串赋值时,此时的字符串存储在方法区的字符串常量池中;
    通过new+构造器方式实例化字符串时,字符串对象存储在堆中,但是字符串的值仍然存储在方法区的常量池中。

String字符串具有不可变性,当字符串重新赋值时,不管是对字符串进行拼接,还是调用String的replace()方法修改指定的字符或字符串,都不会在原来的内存地址进行修改,而是重新分配新的内存地址进行赋值。


StringBuffer

StringBuffer对象代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。任何对它所指代的字符串的改变都不会产生新的对象。通过StringBuffer生成的字符串,可以调用toString()方法将其转换为一个String对象。

例如:

StringBuffer b = new StringBuffer("123");
b.append("456");

System.out.println(b);	// b打印结果为:123456

在看一下b对象的内存空间图:

在这里插入图片描述

可以看到它没有重新生成一个对象,而且在原来的对象中可以连接新的字符串。所以说StringBuffer对象是一个字符序列可变的字符串。


StringBuilder

StringBuilder类也代表可变字符串对象。实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同。不同的是:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高。StringBuffer是如何实现线程安全的呢?
StringBuffer类中实现的方法:
在这里插入图片描述

StringBuilder类中实现的方法:在这里插入图片描述

可以看到,StringBuffer类中的方法都添加了synchronized关键字,也就是给这个方法添加了一个锁,用来保证线程安全。


StringBuffer和StringBuilder的区别

img

  1. 线程安全

    StringBuffer 线程安全,StringBuilder 线程不安全。因为 StringBuffer 的所有公开方法都是 synchronized修饰的,而 StringBuilder 并没有synchronized修饰。

  2. 缓冲区

    StringBuffer 每次获取 toString 都会直接使用缓存区的 toStringCache 值来构造一个字符串。StringBuffer 的这个toString 方法仍然是同步的。

    而 StringBuilder 则每次都需要复制一次字符数组,再构造一个字符串。

  3. 性能

    StringBuffer 是线程安全的,它的所有公开方法都是同步的,StringBuilder 是没有对方法加锁同步的,所以StringBuilder 的性能要大于 StringBuffer。

    StringBuffer 适用于用在多线程操作同一个 StringBuffer 的场景,而 StringBuilder 更适合单线程场合。


String、StringBuffer和StringBuilder的异同

相同点: 都用来代表字符串,底层都是通过char数组实现的。
不同点:

  1. String类是不可变类,String对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的;即任何对String的改变会引发新的String对象的生成。

  2. StringBuffer和StringBuilder类则是可变类,他俩的原理和操作基本相同,任何对它所指代的字符串的改变都不会产生新的对象。StringBuffer几乎所有的方法都使用synchronized实现了同步,支持并发操作,线程安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder线程不安全,不支持并发操作,不能同步访问,不适合多线程中使用。但是效率比较高。

  3. 需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费;推荐需要使用 StringBuffer 和 StringBuilder 类。当需要考虑线程安全的场景下使用 StringBuffer,如果不需要考虑线程安全,追求效率的场景下可以使用 StringBuilder。


感谢大家的耐心阅读,如有建议请私信或评论留言
举报

相关推荐

0 条评论