文章目录
- 区别一:字符串内容是否可变
- 区别二:线程安全
- 区别三:性能
- 区别四:使用场景
“String,StringBuffer以及StringBuilder之间的区别的区别” 这个问题是面试官比较常问的一个Java基础题。在日常的开发中,也常常会用到它们。
区别一:字符串内容是否可变
String不可变,StringBuffer、StringBuilder可变
String类是不可变类,对String类的修改实际上是生成了一个新的对象,并将原来的String类对象指向这个对象;意思就是它本身并没有改变,只是它的引用变了。String不可修改指的是对象本身不可修改,而不是引用不可修改。
StringBufffer 和 StringBuilder 是可变的,它是通过提供的append,insert,reverse,setCharAt,setLength等方法来改变这个字符串;它的改变不是重新生成对象,而是对原字符串进行处理。
代码示例:
为什么String不可变?
我们可以来看下String的源码
从源码中我们可以得知,String 类以及它的成员变量都是用关键字 final 修饰的,这里扩展一下final关键字的知识点 final 关键字修饰的类不能被继承,修饰的方法不能被重写,修饰的变量是基本类型则初始化后不能被改变
所以我们得出String不可变的原因有两点:
1.被 final 修饰导致其不能被继承,因此无法有子类能继承它,避免了子类破坏String的不可变
2.保存字符串的数组被 final 修饰且为私有的,并且String 类没有向外提供修改这个字符串的方法
为什么StringBuffer和StringBuilder可变?
主要是得益于它们对外提供/暴露的append等方法。append的原理就是改变了StringBuffer或者StringBuilder内部的字符数组内容,因此是可变的
源码:
区别二:线程安全
StringBuffer是线程安全的,StringBuilder是线程不安全的
String就不用说了,它肯定是线程安全的,因为它是不可变的。
因为 StringBuffer 的所有公开方法都是 synchronized 修饰的,用关键字synchronized 修饰后,就是加锁同步,能保证同一时刻只能有一个线程访问共享资源
。而 StringBuilder 并没有。从下图中它们各自的源码中就可以看出来了
区别三:性能
StringBuilder >> StringBuffer >> String
因为StringBuilder 是没有对方法加锁同步的,既然 StringBuffer的所有公开方法都是同步的,因此StringBuilder 的性能要远远大于StringBuffer。
代码示例:
区别四:使用场景
String:适用于少量的字符串操作的情况。
StringBuffer:适用于多线程下进行大量操作的情况。
StringBuilder:适用于单线程下进行大量操作的情况。
点赞、收藏不迷路!