String,StringBuffer,StringBuilder的区别

一、相同点

1.都是final类,不允许被继承。之所以使用final,是因为这几个类使用频率很高,防止其中方法被重写。

二、不同点

1.运行速度:StringBuilder > StringBuffer > String。

2.线程安全:StringBuffer 是线程安全的,StringBuilder是线程不安全的。

三、深层次解析

1.为啥String速度最慢?

     这里说的速度慢,是指在执行修改操作时,三者的速度比较。String是字符串常量,不可变的。例如以下代码:

public static void main(String[] args) {
   String str="hello";          
   str= str + "123";     //创建一个str引用的拷贝,然后创建一个新对象“hello123”,引用指向新对象。
   System.out.println(str); //原来的str在引用指向新对象的时候,就会被gc回收掉
}

 StringBuffer与StringBuilder则是字符串变量,可变的,没有进行对象的创建与销毁,所以速度略快。而StringBuilder 的速度之所以大于StringBuffer,是因为StringBuffer是线程安全的,它的操作都是被synchronized修饰,所以在性能上有所下降。例如源码:

StringBuffer类
@Override
public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; }


StringBuilder类
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}

2.重载+ 与StringBuilder

我们看下面两段代码:第一段编译器首先会自动优化程序,将自动引入StringBuilder来执行,但是由于每个循环中都要 new StringBuilder(),还要销毁对象,所以耗时很长,达到270ms。第二段代码则直接使用StringBuilder,不存在反复的创建与销毁对象,所以运行速度很快。所以在拼接长字符串时,不考虑线程安全的情况,使用StringBuilder最好。

public static void main(String[] args) {
    long stime = System.currentTimeMillis();
    String s="hello";
    for(int i = 0;i<10000;i++){
        s = s + i;
    }
    long etime = System.currentTimeMillis();
    System.out.println(s);
    System.out.println(etime-stime);
 }
结果耗时大约:273ms
public static void main(String[] args) {
        long stime = System.currentTimeMillis();
        StringBuilder s= new StringBuilder();
        s.append("hello");
        for(int i = 0;i<10000;i++){
            s.append(i);
        }
        long etime = System.currentTimeMillis();
        System.out.println(s.toString());
        System.out.println(etime-stime);
    }
结果耗时大约:
2ms
 

 

posted @ 2017-10-28 12:53  井井凉风  阅读(824)  评论(0编辑  收藏  举报