类型  是否可变  线程安全  能否频繁修改 
String  不可变  安全  否 
StringBuffer  可变  安全  能 
StringBuilder  可变  不安全 

1、可变与不可变 

  String中保存的是字符串常量,字符数组定义为final类型的,因此String对象是不可变的。

    private final char value[];

  StringBuffer和StringBuilder都继承同一个抽象类AbstractStringBuilder,该父类中使用字符数组保存字符串,是可变对象。  

    char[] value;

2、线程是否安全

  String中保存的是字符串常量,不可改变字符串的值,是线程安全的。

  StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append()。但是StringBuffer中对自身方法或调用的方法加了同步锁,是线程安全的。StringBuilder没有加同步锁,因此StringBuilder是线性不安全的,适合于单线程操作,其性能比StringBuffer略高。

3、可否频繁修改

(1)String

  当String使用引号创建字符串时,会先去字符串池中找,找到了就返回,找不到就在字符串池中增加一个然后返回,这样由于共享提高了性能。

  而new String()无论内容是否已经存在,都会开辟新的堆空间,栈中的堆内存也会改变。每次对String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用String 。在修改变量值时使其反复改变栈中的对于堆的引用地址,所以性能低。每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。因此不要使用String类的"+"来进行频繁的拼接

  在某些特别情况下,String 对象的字符串拼接其实是被 Java Compiler 编译成了 StringBuffer 对象的拼接,所以这些时候 String 的速度并不会比 StringBuffer 对象慢:

        String s1 = “This is only a” + “ simple” + “ test”;
StringBuffer sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

  在这种情况下,生成 String s1对象的速度并不比 StringBuffer慢。其实在Java Compiler里,直接把上述第一条语句编译为:String s1 = “This is only a simple test”;

所以速度很快。但要注意的是,如果拼接的字符串来自另外的String对象的话,Java Compiler就不会自动转换了,速度也就没那么快了,例如:

  String s2 = “This is only a”;
  String s3 = “ simple”;
  String s4 = “ test”;
  String s1 =  s2 + s3 + s4;

  这时候,Java Compiler会规规矩矩的按照原来的方式去做,String的concatenation(即+)操作利用了StringBuilder(或StringBuffer)的append方法实现,此时,对于上述情况,若s2,s3,s4采用String定义,拼接时需要额外创建一个StringBuffer(或StringBuilder),之后将StringBuffer转换为String;若采用StringBuffer或StringBuilder,则不需额外创建StringBuffer。

(2)StringBuffer和StringBuilder

  相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因此除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用StringBuilder;否则还是用StringBuffer。

  为了获得更好的性能,在构造 StringBuffer 或 StringBuilder 时应尽可能指定它们的容量。当然,如果你操作的字符串长度(length)不超过 16 个字符就不用了,当不指定容量(capacity)时默认构造一个容量为16的对象。不指定容量会显著降低性能。

Java中的String、StringBuffer和StringBuilder的区别的更多相关文章

  1. Android/Java 中的 String, StringBuffer, StringBuilder的区别和使用

    Android 中的 String, StringBuffer 和 StringBuilder 是移动手机开发中经常使用到的字符串类.做为基础知识是必须要理解的,这里做一些总结. A.区别 可以从以下 ...

  2. 在JAVA中,String,Stringbuffer,StringBuilder 的区别

    首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String  不是线程安全的,这意味着在不同线程共享一个String ...

  3. 重温java中的String,StringBuffer,StringBuilder类

    不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...

  4. java中String,StringBuffer与StringBuilder的区别??

    本文着重介绍下,应该在何时恰当的使用string,stringbuffer,stringbuilder. 1,执行速度 StringBuilder >  StringBuffer  >  ...

  5. JAVA String,StringBuffer与StringBuilder的区别??

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  6. 【Java】String,StringBuffer与StringBuilder的区别??

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  7. String,StringBuffer与StringBuilder的区别??

    转自http://blog.csdn.net/rmn190/article/details/1492013 String 字符串常量 StringBuffer 字符串变量(线程安全) StringBu ...

  8. 转 String,StringBuffer与StringBuilder的区别??

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  9. String,StringBuffer与StringBuilder的区别??[转]

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  10. String,StringBuffer与StringBuilder的区别?? 缓存

    转: String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主 ...

随机推荐

  1. android 自定义控件之事件

    首先,继承需要扩展的VIEW,然后在里面添加一个自己的事件方法,例如, oniconclick(myinterface pinterface){ minterface = pinterface; } ...

  2. __tostring和__invoke 方法

    首先放上代码: <?php class MagicTest{ //__tostring会在把对象转换为string的时候自动调用 public function __tostring() { r ...

  3. js转化与排序

    1.对象转化为数组 object.keys() var obj={a:3,b:7,c:8,d:false} alert(Object.keys(obj)) 注意此函数会把对象的key转化为数组 spl ...

  4. SpringBoot07 异常枚举、自定义异常、统一的全局异常处理

    1 异常编号和提示信息统一管理 利用枚举来实现异常的统一管理 package cn.xiangxu.springboottest.enums; import lombok.Getter; /** * ...

  5. Tensorflow 优化学习

    # coding: utf-8 import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data pr ...

  6. 34- 24 Point game

    http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=43 24 Point game 时间限制:3000 ms  |  内存限制:65535 KB ...

  7. Spring第五天

    1. [简答题]:简述一下hibernate和spring框架的整合步骤: 答: 1.加入hibernate jar包 2.编写持久化类 3.添加Hibernate的配置文件:hibernate.cf ...

  8. ZROI2018提高day9t1

    传送门 分析 我们首先想到的自然是根据大小关系建图,在这之后我们跑一遍拓扑排序 但是由于l和r的限制关系我们需要对传统的拓扑排序做一些改变 我们考虑将所有入度为0且现在的拓扑序号已经大于等于l的点放入 ...

  9. javascript 基础练习 做Bingo图

    ---恢复内容开始--- <!DOCTYPE html><html>    <head>        <meta charset="utf-8&q ...

  10. 树莓派研究笔记(10)-- Retropie 模拟器

    前面介绍过lakka模拟器,小巧,轻便,支持中文.其实最著名的游戏系统还是要属于Retropie啊.虽然笨重了一点,但是很多树莓派系统的原汁原味还是保留的很好.这样就不需要我们自己还要对lakka的源 ...