图解Java中String、StringBuffer和StringBuilder的区别

图解Java中String、StringBuffer和StringBuilder的区别
参考博客:https://blog.csdn.net/weixin_41101173/article/details/79677982

一、Java中的 String 类——String 是字符串常量
1、字符串广泛应用在Java 编程中,在Java中字符串属于对象,Java提供了String类来创建和操作字符串。需要注意的是,String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。我们来看一下这张对String操作时内存变化的图:

2、我们可以看到,初始化String的值为“hello”。然后在这个字符串后面加上新的字符串“world”,这个过程是需要重新在堆内存中开辟内存空间的,最终得到了“hello world”字符串也相应的需要开辟内存空间。这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费。为了应对经常性的字符串相关操作,谷歌引入两个新的类——StringBuffer类和StringBuilder类来对此种变化字符串进行处理。

二、Java中的StringBuffer类和StringBuilder类——StringBuffer字符串变量、StringBuilder字符串变量

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

2、和String类不同的是,StringBuffer类和 StringBuilder类的对象能够被多次修改,并且不产生新的未使用对象。

StringBuilder类在Java5中被提出,它和StringBuffer类之间最大的不同在于:

StringBuffer类的方法是线程安全的,可以同步访问,速度慢;StringBuilder类的方法不是线程安全的,不能同步访问,速度快。

3、正是由于StringBuilder类相较于StringBuffer类有速度优势,所以多数情况下建议使用StringBuilder类。然而在应用程序要求线程安全的情况下,则必须使用StringBuffer类。

4、三者的继承结构如下图所示:

5、三者的区别:

(1)字符串修改上的区别:主要见上面分析。

(2)初始化上的区别:String可以空赋值,后者不行,报错

String类:
String str = null;   
String str = “abc”;
 

StringBuilder类和StringBuffer类:
StringBuilder sb = null;    //结果警告:Null pointer access: The variable result can only be null at this location
StringBuilder sb = new StringBuilder();    //StringBuffer对象是一个空的对象
StringBuilder sb = new StringBuilder(“abc”);    //创建带有内容的StringBuffer对象,对象的内容就是字符串”
 
StringBuffer sb = null;    //结果警告:Null pointer access: The variable result can only be null at this location
StringBuffer sb = new StringBuffer();    //StringBuffer对象是一个空的对象
StringBuffer sb = new StringBuffer(“abc”);    //创建带有内容的StringBuffer对象,对象的内容就是字符串”
 

一、String、StringBuffer与StringBuilder之间区别
1、首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String

(1)String最慢的原因:String为字符串常量,而StringBuilder和StringBuffer均为字符串变量。即,String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

(2)以下面一段代码为例:

String str="abc";
System.out.println(str);
str=str+"de";
System.out.println(str);
如果运行这段代码会发现先输出“abc”,然后又输出“abcde”,好像是str这个对象被更改了,其实,这只是一种假象罢了,JVM对于这几行代码是这样处理的:首先创建一个String对象str,并把“abc”赋值给str;然后在第三行中,其实JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了。所以,第一次创建的那个str对象实际上并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。

(3)而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

(4)另外,有时候我们会这样对字符串进行赋值:

String str="abc"+"de";
StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
System.out.println(str);
System.out.println(stringBuilder.toString());
这样输出结果也是“abcde”和“abcde”,但是String的速度却比StringBuilder的反应速度要快很多。

这是因为第1行中的操作和 String str="abcde"; 是完全一样的,所以会很快;而如果第一行写成下面这种形式  String str1="abc";  String str2="de";  String str=str1+str2;  那么JVM就会像上面说的那样,不断的创建对象、回收对象来进行这个操作了,速度就会很慢。

2、再来说线程安全

(1)在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。

如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的。但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。

所以如果要进行的操作是多线程的,那么就要使用StringBuffer;但是在单线程情况下,还是建议使用速度比较快的StringBuilder。

3、总结一下

String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
--------------------- 
作者:stormchenmeng 
来源:CSDN 
原文:https://blog.csdn.net/cmm0401/article/details/81735247 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/u010112268/article/details/84111504
今日推荐