String、StringBuffer

来源:互联网 发布:淘宝网店运营策划案 编辑:程序博客网 时间:2024/06/02 05:29

这个话题貌似是面试必问的问题了,我也认认真真的学习了一下,下面是我的一些愚见~

1.String类代表了字符串,是常量,因此是不可变的。

String类的源码中有这样一段代码:

/** The value is used for character storage. */ private final char value[];

这是一个final修饰的不可变的数组,注释说明它是用来存放字符的容器,也就是说,String字符串中的字符是被存放在一个final修饰的数组里,final修饰变量是什么意思不用多说了吧,就是说明了这个变量不可变。
有些编程的代码中,却是有形如:

public class ReviseDemo {    public static void main(String[] args){        String s=new String("abc");        System.out.println(s+"d");    }}

可以看出这段代码的运行结果是abcd。
但是并不是否定了”String是不可变的“,实际上是这样运行的:
1)首先创建一个引用名为s的String对象,且该对象的值为abc
2)在执行s+“d”的时候,java系统是又隐式的新建了一个String对象,对象的引用名称也是s,但是这个对象已经不是原来的那个对象了,原来的对象已经被当做垃圾被GC回收掉了。
所以说String是不可变的。
既然使用String对象改变字符串的时候每次都要涉及对象的新建和回收,那效率可想而知就是不高的,所以就有了StringBuffer。
2.StringBuffer是可变的字符串
StringBuffer有一个append方法,用于向StringBuffer中添加元素。StringBuffer的默认容量大小是16个字符,StringBuffer每次扩容的时候是实际长度×2+2,但是每次都需要重新构造新的字符数组(直到满足容量要求),将原字符数组的数据拷贝到新的字符数组中,原字符数组被回收。显然这样会增加性能开销,所以一般我们在使用的时候需要大致估算一下长度,指定StringBuffer的容量,减少扩容次数,提高性能。
另外,StringBuffer类的有关操作字符串的方法都是用synchronized修饰的,即是线程同步的,所以是
线程安全的,适合在多线程环境下使用,它还有一个轻量级的实现,即StringBuilder,这个类和StringBuffer一样,都表示可变字符串,但是StringBuilder是非线程安全*的,在单线程环境下比较合适。由于不是线程同步的,所以StringBuilder效率要比StringBuffer高。

总结:
1.如果存储少量字符且不会频繁修改字符串,选择String
2.如果存储多量字符串,单线程下选择StringBuilder,多线程下选择StringBuffer

原创粉丝点击