Java 中 String、StringBuffer 和 StringBuilder 的区别与联系

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/yichen97/article/details/90755384

引言 

这题应该是最最经典的一轮必问了,三个亲兄弟问的多了,网上自然而然被整理的也很多。我觉得我自己也应该整理一篇,以加深自己的印象,不至于假如真的有哪一天被问到了,答不出个所以然来。

String

源码位置(Android O):/libcore/ojluni/src/main/java/java/lang/String.java

1. String对象非基本数据类型,存储在堆中;

2. 源码显示:

String类为final类,所以不能被继承,并且一旦被创建,就无法改变它的值。

String既然是final类,那么它是究竟怎么操作的呢?

假如说有这样一段代码:

String str = "hello";
str = str + "world";

答:1. JVM先创建了一个String对象str,并将"hello"赋值给str;

2. 再创建一个新的String对象str;

3. 把"hellp"和"world"合起来赋值给了新的str;

4. 由于大量的String拼接操作,JVM会出现内存紧张,基本上都会实时进行GC,引起运行变慢。

这些操作在JVM是这样子的:

所以:对String的操作是一个不断创建新的对象和回收老对象的过程。

值得注意的一点:

String str = "hello" + "world";

StringBuilder stringBuilder = new StringBuilder().append("hello").append("world");

前者要比后者快得多。因为前者这段代码等同于:

String str = "helloworld";

StringBuffer

源码位置(Android O):/libcore/ojluni/src/main/java/java/lang/StringBuffer.java

StringBuffer是一个类似于String的字符缓冲区,且为字符串变量;在实际的使用中,最常用的是它的append()方法和toString()方法,先用append()方法将字符串拼接,返回的时候用toString()方法将该拼接完成的对象以字符串的形式返回。

因为StringBuffer为字符串变量,那么他的拼接速度肯定是要比String要快了,但刚要打开它的源码,就发现映入眼帘的synchronized关键字,存在这些互斥,它的性能肯定是要受很大影响的。

StringBuilder

源码位置(Android O):/libcore/ojluni/src/main/java/java/lang/StringBuilder.java

StringBuilder的源码好像与StringBuffer的差距并不是很大,但与StringBuffer差距较明显的是,synchronized关键字都没有了。

缺少了synchronized关键字,StringBuilder方法的运行便不受互斥的影响,有调用即可运行,那它的性能肯定是要比StringBuffer的速度要快。当然,有得也有失,synchronized关键字可以保证在多线程的情况下保持线程安全,所以,StringBuilder只能在单线程中使用,在多线程中,必须使用StringBuffer。

三者运行速度的对比

StringBuilder > StringBuffer > String

因为String是常量,无法完成拼接字符串,只能不停创建新对象和回收老对象,所以速度最慢;

StringBuffer虽然是字符串变量,但它的方法里做了很多互斥,一个方法结束后,将锁释放,再进行下一步操作,所以比String快,但还不够快;

StringBuilder既是字符串变量,在方法中也不像StringBuffer那样做很多限制,所以速度最快。

三者线程安全的对比

String、StringBuffer为线程安全的;StringBuilder为线程不安全的。

String为不可变量,所有的不可变量都是线程安全的,所以String线程也是线程安全的;

StringBuffer加了那么多synchronized,为此消耗了很多的性能,线程也是安全的;

StringBuilder因为什么都没干,得到了速度,失去的就是线程的安全。

结论

String:适合用在对字符操作少的情况;

StringBuffer:适合在多线程的情况下对字符串进行大量的操作;

StringBuilder:适合在单线程的情况下对字符串进行大量操作。

参考文献

Java中的String,StringBuilder,StringBuffer三者的区别

StringBuffer与StringBuilder的区别,及实现原理

猜你喜欢

转载自blog.csdn.net/yichen97/article/details/90755384