字符串-String、StringBuilder、StringBuffer的区别

字符串操作是计算机程序设计中最常见的行为。

String

一般声明一个字符串类型,常用的是String类,String对象是不可变的。String类中每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容。

String中如何实现不可变设计?

查看String类的源码可以看到:

发现该类、类中的属性都是final的,在此回顾final修饰的意义:

1)属性用final修饰保证了属性时只读的,不能修改;

2)类用final修饰保证了该类中的方法不能被覆盖,该类不能被继承,防止子类无意间破坏不可变性

看个String不可变的例子 :

可以看到q的值没有变过,这是因为当q传给upcase()方法的时候,实际上传递是一个引用的拷贝。其实,每当把String对象作为方法的参数的时候,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。

String中的“+”

 在这个例子中,编译器创建了一个StringBuilder对象,用以构造最终的q,并为每个字符串调用一次StringBuilder中的append方法,最后调用toString()生成结果,并重新存为q。

保护性拷贝(String要考虑线程安全问题吗?)

有时候我们会注意到,使用字符串的时候,也有一些修改相关的方法,比如substring(),接下来看看这个方法的底层源码:

发现其内部是调用了String的构造方法创建了一个新的字符串,再进入这个构造方法看看,是否对final char value[]做出了修改:

并没有对final char value[]做修改,构造新的字符串对象时,会生成新的char[] value,对内容进行复制。这种通过创建副本的方法来避免共享的手段称之为保护性拷贝。这也是为什么String不需要考虑线程安全问题。

StringBuilder

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

查看StringBuilder底层代码:

发现调用的都是父类构造器,再到父类中看:

发现value并不是final类型。不存在不可变性。

StringBuffer

StringBuffer是可变的,并且是线程安全的,其线程安全是因为每个方法加了synchronized关键字。

StringBuffer与StringBuilder除了线程安全的区别没有太大区别,但是一般线程安全的话,效率会降低,所以StringBuilder的效率高于StringBuffer。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值