Java面试题四:String,StringBuffer,StringBuilder之间的区别

    String,StringBuffer,StringBuilder都是代表字符串。

    String类是不可变的类,任何让String类的改变都会让String类产生一个新的对象。

    StringBuffer是可变类,任何StringBuffer字符串的改变都不会产生一个新的对象。StringBuffer是String字符串的一个缓冲区,对于String来说,StringBuffer是可以改变的,StringBuffer是线程安全的。有几个线程同时操作StringBuffer序列,所有操作串行执行。每一个StringBuffer都有一个容量,如果内容大小超过容量,StringBuffer会产生一个更大的缓冲区,StringBuffer和StringBuilder的操作相同,StringBuilder是线程不安全的。

表格:

String,StringBuffer,StringBuilder之间的区别
String StringBuffer StringBuilder
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量优先的内存空间  StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量  和StringBuffer的操作相同, 也是可变类,速度更快
不可变 可变 可变
  线程安全 线程不安全
  多线程操作字符串 单线程操作字符串

注意:

        String有个使用的陷阱:

                      String s = "a",s = s + "b"。

                      编译器实际上已经把a进行丢弃,现在产生了一个新的字符串"ab",如果多次执行这些操作,会残留大量的副本存留在内存中,降低了效率,增加了JVM垃圾回收的负担。

        StringBuffer s = null; //结果警告:Null pointer access: The variable result can only be null at this location

        StringBuffer s = new StringBuffer();//StringBuffer对象是一个空的对象

        StringBuffer s = new StringBuffer(“abc”);//创建带有内容的StringBuffer对象,对象的内容就是字符串”

        StringBuffer与StringBuilder的线程安全性问题,为什么StringBuilder执行的速度更快?

扫描二维码关注公众号,回复: 12794719 查看本文章

            ① 线程安全方面,StringBuffer运行多线程字符串操作。源代码中StringBuffer中的方法很多都被synchronize修饰了,而StringBuilder没有。synchronize是线程同步锁机制。     

            ② 每一个类对象都应该是一把锁,当某个线程A调用对象B中同步锁机制synchronize方法M时,必须获得对象B的锁才能执行M方法,否则线程A就会阻塞。一旦线程A开始执行M方法,将独占对象对象B的锁,使得其他调用B对象的M方法的线程阻塞。只有A执行完毕,释放后,那么阻塞的线程才有机会重新调用M方法。这就是解决线程同步问题的锁机制。

            ③ 如果有多个线程需要对同一个字符串缓冲区进行操作的时候,StringBuffer是很好的选择,因为StringBuffer是多线程机制。

      StringBuilder的效率比StringBuffer稍高,如果不考虑线程安全,StringBuilder应该是首选。另外,JVM运行程序主要的时间耗费是在创建对象和回收对象上。

    

总结:

     String是不可变对象,每次使用的时候都会生成一个新的String对象,然后将指针指向新的String对象,这样不仅效率低下,还会浪费大量的内存空间,所以经常改变内容的字符串最好不要使用String。

对字符串进行修改的时候,特别是字符串对象经常改变的情况下,需要使用 StringBuffer 和 StringBuilder类。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

参考:https://blog.csdn.net/itchuxuezhe_yang/article/details/89966303

猜你喜欢

转载自blog.csdn.net/Sunshineoe/article/details/114888546