关于String和StringBuffer和StringBuilder之间区别理解

1.首先我们讨论String类:

       关于String和StringBuffer和StringBuilder之间区别理解

   我们可以看到String类被final所修饰,至于类被final修饰无非就是为了让这个类不被继承和重写它里面的方法,所以说这里修饰类的final是起到了安全的作用(并不是String不可变的原因)。接下来可能有人就会说了value被final修饰了那么肯定是不可变的因素了,那么你就大错特错了。

关于String和StringBuffer和StringBuilder之间区别理解

如上图所示被final修饰的数组我依然可以修改它的内部内容。原因是什么呢?根据对jvm的理解,当我们创建一个对象,那么变量会在stack上,而真正的对象内容会在heap堆里面,我们之所以能访问内容是因为变量会引用指向对象内容。而被final修饰的数组只是将引用地址不可变而已。

那么真正能让String不变的原因是什么呢?

String不可变是它底层设计的巧妙性,而不单单是因为两个final。

在这里我也可以用一个反射来证明String类的value数组是可变的

关于String和StringBuffer和StringBuilder之间区别理解

   到这里我们在玩玩其他关于String的有趣的东西吧:

关于String和StringBuffer和StringBuilder之间区别理解

废话不多说直接解释原因:

首先,当我们String使用字符串的时候,首先会访问方法区的常量池,若是常量池没有这个字符串,那么会创建后放入常量池,并指向常量池的字符串。若是有则直接引用常量池的字符串,这样可以大大减少堆空间的浪费。所以a和b的引用地址都是一样的,同时都是指向常量池的a字符串。那么为什么b==v是false呢?因为你首先new了,new了后堆空间肯定会先创建一个对象,那么string是指向对象而不是常量池,真正指向常理池的是对象(本身是个数组时有引用的)的引用地址。所以他两是不相等的。

那么关于String类的理解先到此位置。

接下来讨论下StringBuffer

关于String和StringBuffer和StringBuilder之间区别理解

StringBuffer是个可变字符串,同时是线程安全的。

相比较于String优点是:它在字符串频繁改变的情况下和多线程的情况下更优于String,因为String是不可变的,你每次改变字符串都会造成空间的浪费。

String a="cc"+"dd";的+操作就是利用了StringBuffer或者StringBuilder的append方法,也就是说当你用+的时候,String就相当于创建个StringBuffer或者StringBuilder然后转型为String。

接下来说说StringBuilder

关于String和StringBuffer和StringBuilder之间区别理解

很显然他不是安全的,并且也不是线程安全的。

但是它也有优点在单线程的情况下运行速度肯定要比StringBuffer快很多。

 

最后来个总结:

在多线程的情况下,StringBuilder多用于方法内部,用完就扔了。而StringBuffer多用于全局变量。String类用于确定不会改变的变量值上。