String、StringBuffer、StringBuilder的区别及使用

不可变类 - String

一如既往,在进行学习之前我们先看看相关的定义吧~下面引自 JavaDocs:

Strings are constant; their values cannot be changed after they are created

String 类是不可变的,String 对象的值在创建后不会发生改变。换句话说,我们平常对 String 对象的操作,实际上都是创建了一个新的 String 对象,将该对象的引用赋给我们的对象,而内存之中仍然存有原来的两个字符串。可能有点绕,大家可以看看下面的代码:

public class Demo {
    public static void main(String[] args) {
        String str;
        String changeStr;

        str = "chaos";
        changeStr = "";

        System.out.println("初始");
        System.out.println(str);
        System.out.println(changeStr);

        changeStr = change(str);
        System.out.println("改变后");
        System.out.println(changeStr);
        System.out.println(str);
    }

    private static String change(String str){
        str = str  + "change";
        return str;
    }
}

输出:

初始

chaos

改变后

chaoschange

chaos

我们可以看到,change() 方法并没有改变 test 的值。为什么呢?因为实际上,传给 change() 方法的是引用的一个拷贝,原对象并没有作为参数被方法修改。

所以 String 具有一个大坑:如果我们没有注意到 String 类的这个特性,将多个频繁发生改变的字符串的对象类型选为 String的话,内存一定会受此影响,从而影响系统性能;此外,当引用过多,还会出发垃圾回收机制,影响性能。

线程安全的 StringBuffer

A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified.

StringBuffer 和 String 的最大区别在于,StringBuffer 是一个可变类,换句话说,StringBuffer 中的值不但可以改变,还不会产生 String 类的副作用(不断创建对象)。此外,StringBuffer 还是线程安全的。例如:

public class Demo {
    public static void main(String[] args) {
        String str;

        StringBuffer sb = new StringBuffer();
        StringBuffer changeSb = new StringBuffer();

        str = "chaos";
        sb.append(str);

        System.out.println("初始");
        System.out.println(sb.toString());

        changeSb = sb;
        changeSb.append("change");
        System.out.println("改变后");
        System.out.println(sb.toString());
        System.out.println(changeSb.toString());
    }
}

输出:

初始

chaos

改变后

chaoschange

chaoschange

所以如果我们的程序中如果存在需要频繁修改值的字符串,最好是使用 StringBuffer,因为除了刚刚提到的“线程安全”和“可变”两个特性以外,每个 StringBuffer 还具有一定的缓冲区容量,只有当字符串大小超过容量上限才会增加容量大小。

那么这样看下来,很多人会觉得 StringBuffer 很完美,以后就用它了!对于这样的同学我想说一句:且慢!!!事实上,StringBuffer 虽然看起来很完美,但它的线程安全实现机制是它最大的弱点,我们先来看看它是怎么实现线程安全的:

@Override
    public synchronized StringBuffer append(boolean b) {
        toStringCache = null;
        super.append(b);
        return this;
    }

我们可以看到,StringBuffer 通过 synchronized 关键字为方法加上同步锁,从而实现线程安全。但如果我们 append 1w 次,那么程序就要负担 1w 次加锁解锁带来的时间消耗,影响了效率。此外,大部分情况下,我们都是在单线程情况下使用 String,不需要考虑到线程安全问题,这就使得 StringBuffer 的加锁/解锁过程为程序带来了不必要的开支。所以在 Effective Java 中就有这么一句话:

Java 1.5发行版本中增加了非同步 StringBuilder 类,代替了现在已经过时的 StringBuffer 类

非线程安全的 StringBuilder

事实上,StringBuilder 的内部实现和 StringBuffer 几乎一样,唯一的区别在于:StringBuilder 中去掉了 synchronized 关键字,失去了线程安全的特性。

我们刚刚也提到了,StringBuffer 的线程安全机制在大多数情况下都不必要,为系统带来的开销完全是不必要的,所以 Java 1.5 发行版本推出了 StringBuilder。

其他方面倒没什么区别,所以最佳方案应该是使用 StringBuilder,如果需要考虑线程安全问题,再考虑 StringBuffer,或者重写 StringBuilder 的相应方法实现线程安全。

时间: 2024-08-28 23:32:31

String、StringBuffer、StringBuilder的区别及使用的相关文章

Java杂谈之StringBuffer----兼带String,StringBuffer,StringBuilder的区别

在Java中,用到最多的当属String类型的数据了 而这一点就要涉及String , StringBuffer , StringBuilder这三大类 下面主要来比较一下String和StringBuffer的区别,因为StringBuffer和StringBuilder 太相似,所以就不拿来比较了. 提及一下,StringBuffer和StringBuilder的区别 从安全性来说,StringBuffer更安全,StringBuffer主打线程安全 从执行效率来说,StringBuilde

String,StringBuffer,StringBuilder的区别

StringBuffer和StringBuider的区别 StringBuffer是jdk1.0版本的,是线程安全的,效率低 StringBuilder是jdk1.5的,是线程不安全的,效率高 String和StringBuffer,StringBuilder的区别 String是一个不可变的字符序列 StringBuffer,StringBuilder是可变的字符序列

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

首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String  不是线程安全的,这意味着在不同线程共享一个String的时候,需要先进行同步,否则会出现不同线程获得的值不同的情况,即线程不安全 StringBuffer 是线程安全的,在不同线程中共享的时候会自动同步,不需要手动同步. 效率方面: String在每次更改的时候均是重新建立一个变量,再将更改后的值赋予其中,多次更改之后会触发JVM的GC机制,占用资源

java String,StringBuffer,StringBuilder的区别

StringBuilder.StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(...).只是StringBuffer会在方法上加synchronized关键字,进行同步. 最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer ? 这句话并不理解. 1 String String:字符串常量,字符串长度不可变.Java中String是immutable(不可变)的. String类的包

转:String StringBuffer StringBuilder区别

转自:http://www.iteye.com/topic/522167 作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸裸的站在我们这些Java色狼面前了.嘿嘿.... 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却不是普通的类哦!!! [镜头1] String对象的创建       1.关于类对象的创建,很普通的一种方式就是利用构造器,

关于Java基础知识 String StringBuffer StringBuilder三者的区别

Java基础中String StringBuffer StringBuilder 以下介绍 相同点:String,StringBuffer,StringBuilder最终底层存储与操作的都是char数组,StringBuffer和StringBuilder都继承了AbstractStringBuilder 不同点:String:char数组是final的,不可变,修改String时实际上是new一个新String对象返回,线程安全,频繁的增删操作时不建议使用 StringBuffer:线程安全(

java中String与StringBuilder的区别

本篇文章介绍了,java中String与StringBuilder的区别. 相信大家对 String 和 StringBuffer 的区别也已经很了解了,但是估计还是会有很多同志对这两个类的工作原理有些不清楚的地方,今天我在这里重新把这个概念给大家复习一下,顺便牵出 J2SE 5.0 里面带来的一个新的字符操作的类—— StringBuilder (先别忙着扔我砖头,我还算清醒,我这里说的不是 C #, Java 也有 StringBuilder 类).那么这个 StringBuilder 和

String, StringBuffer, StringBuilder比较

1.见API: String是不可变的字符序列: StringBuffer是线程安全的,可变的字符序列: StringBuilder是可变的字符序列: StringBuffer与String的区别是StringBuffer是可变的(StringBuffer看做可变的String),StringBuffer中含有的字符序列和自身长度可随着方法调用而改变:StringBuffer在多线程环境中是安全的,必要的方法都是同步的,因而在某一特定实例上的所有方法就像被依次执行一样,与所有方法依次执行的结果一

Java学习笔记--String StringBuffer StringBuilder

String StringBuffer StringBuilder String http://docs.oracle.com/javase/7/docs/api/ 中文: http://www.cnblogs.com/YSO1983/archive/2009/12/07/1618564.html String str0 = "最正常的创建方法"; System.out.println(str0); char[] c1 = new char[3]; c1[0] = 'c'; c1[1]

String StringBuffer StringBuilder (转)

转自:http://www.iteye.com/topic/522167 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却不是普通的类哦!!! [镜头1] String对象的创建        1.关于类对象的创建,很普通的一种方式就是利用构造器,String类也不例外:String s=new String("Hello world"); 问题是参数"Hello world"是什么东西,