String、StringBuffer、StringBuilde

2019-09-26  本文已影响0人  那一只羊

光看不如手搓!

如果这是一个面试问题,那么大多数人可能会这么回答:String由final修饰是不可变的;StringBuffer是线程安全的;StringBuilder是线程不安全的。

那应用场景是什么?

String:

          不可变的序列,运用在字符串不经常变化的方法中。String在Java中提供了+运算符来进行拼接。但这里有一个性能问题,String在JVM中其实是new的StringBuilder对象,利用append方法来处理的,对性能是有所影响的。

比如这段代码:

我们检查它的字节码发现它其实是new了2次StringBuiler,开辟新的内存空间:

StringBuilder:

StringBuilder的出现其实就是为了解决大量字符串通过String来拼接导致不停的开辟内存空间,降低内存的消耗。

比如这段代码:

为什么会给一个capacity的值呢?

因为StringBuilder是继承的AbstractStringBuilder。底层其实是一个char数组

数组在容量空间不足的情况下是需要扩容的。就是重新创建一个新的数组,然后将旧的数据copy过去。对性能是有一定的影响的,特别是我们在循环中用到String、StringBuilder,StringBuffer。而循环的次数是根据数据库数据或者其他不定参数来的。要小心使用。

来看看编译后的字节码:

只创建了一次。

StringBuffer:

StringBuffer用法和StringBuilder类似的。都是继承的AbstractStringBuilder,也会存在容量扩容的问题。但是StringBuffer是线程安全的。在并发编程中,涉及字符串的操作,应该注意使用StringBuffer。

我们可以看到,StringBuffer的方法是加了同步锁synchronized

总结一下:

String:在对字符串操作不是特别频繁下用String。String在定义的时候会去检查Java的常量池。比如String a ="bbb"。jvm会去检查常量池,这样就不会去创建新的对象了。

StringBuffer:对大量字符串进行操作,线程安全,在多线程场景下应该使用。

StringBuilder:对大量字符串进行操作,线程不安全,在单线程场景下应该使用。

注意事项:

1.我们在日常开发中,String是最常使用的。在我们针对循环的字符串拼接的时候,一定要注意,因为String在最终会被JVM优化成用StringBuilder。那么存在频繁的创建新的对象,导致资源浪费。

2.在使用StringBuilder和StringBuffer的时候,可以考虑给出容量具体的值,这样避免在循环拼接的时候,导致底层扩容,降低效率。

上一篇下一篇

猜你喜欢

热点阅读