String、StringBuffer和StringBuilder的比较

看了很多博客,对String、StringBuffer和StringBuilder的区别主要有以下几点:

1、String是不可变的,是字符串常量,StringBuffer和StringBuilder是可变的,是字符串变量,可以查看它们的定义

下面这个是String类的定义,将String类型定义为final,也即是在定义后不可被改变,也不允许被继承。



下面的是StringBuffer类的定义,这里将其定义为transient类型,百度了一下,transient是Java的关键字,变量修饰符,如果用transient生命一个实例变量,当对象存储时,它的值不需要维持,换句话说,用transient关键字标记的成员变量不参与序列化过程。具体的过程,可自行去了解,这里暂不涉及。


关于StringBuilder类的定义,没有看到字段的定义,但StringBuilder和StringBuffer都是继承了AbstractStringBuilder类的。


2、String是不可变的,可以理解为常量,因此是线程安全的,StringBuffer是线程安全的,StringBuilder是非线程安全的。原因见下

下面是StringBuffer中的部分方法的定义,在StringBuffer中,大部分的方法的定义都是使用了synchronized关键字定义的,即是同步的,因此是线程安全的


而StringBuilder类的定义中,没有使用synchronized关键字定义。


3、一般来说,在效率上,StringBuilder>StringBuffer>String,解释如下:(引用的网址:https://www.oschina.net/code/snippet_109648_2140)

(1)String类是不可变类,因此每次改变变量的值时,都是新生成一个对象,然后再将对象引用指向新的对象,因此速度很慢;

(2)StringBuffer类是直接操作对象引用,刚刚说了StringBuffer是可变的,那么修改变量的值时,是不会产生新对象,因此效率会较好,但在加同步锁时,会消耗性能;

(3)StringBuilder类是JDK5后新增的,用法与StringBuffer一样,但因为它是非线程安全的,不需要加同步锁来维护线程安全,因此较StringBuffer快。


接下来想说一下为什么String是不可变的,为什么要用final声明,不能被继承?我一开始的想法是这样的:因为某一些字符的使用比较频繁,那么如果是不可变的话,就可以在建立新的对象引用,且需要使用之前创建过的对象,那么就不需要再次创建,而是将引用指向之前创建的对象,因此就将它定义为不可变了。继承的话,final修饰的类是不可以被继承的。

然而我的想法欠考虑了很多东西,也看出来我对很多东西确实不是很明白,比如垃圾回收机制,以及对象创建的机制之类的,这些知识要好好补充。

拉回正题,说说什么是不可变类吧:

	String str = "abc";
	str = "abcd";
上面对字符串对象str有两次赋值,实际过程是这样的:

对于第一条str = "abc“,有这样的过程,在内存中创建abc对象,再将str引用指向该对象;

对于第二条语句,str = "abcd",在这个过程中,不会去改变原来已存在的abc对象,而是新创建一个abcd对象,再将str引用指向abcd对象,而abc对象还是存在,不会被覆盖的,等待被垃圾回收器回收。


下面解释为什么要不可变,主要的原因就是安全。

(1)下面这个是在String类定义中的一段话,说了因为String对象是不可变,那么是可以共享的,可以反过来看,对于共享变量的话,在多线程中,那么需要保证它是安全的,不能被修改,如果String是可变的,在多线程中被多个线程使用时,如果被其中一个线程改变了值,那么其他线程中引用的值也会被改变,这样会带来线程不安全的后果。将String声明为final也是为了避免这样的情况。


(2)不允许任何人定义String的子类,换言之,如果有一个String的引用,它引用的一定是一个String对象,而不可能是其他类的对象。 --《Java核心技术 卷1》

(3)String类和基本类型不同,它是对象类型,但是要像其他的基本类型一样在main中被调用的话,要不实例化,要不就是静态的,那么用final来修饰String的话,就可以像基本类型那样使用String。

(4)安全。Java并不是操作系统的本地语言,换句话说,Java必须借助操作系统的帮助才能工作,JDK中提供了很多核心类,比如String,类的内部方法的实现并不是完全由Java本身编写的,而是调用了操作系统的API,如果String可以被继承,那么这些方法可能会被重写,那么这就对我们的操作系统很有可能造成危害,易被攻击。


参考:

http://blog.csdn.net/fenglibing/article/details/5486449

http://blog.csdn.net/qq_27093465/article/details/52190915

https://www.zhihu.com/question/31345592

http://www.cnblogs.com/xudong-bupt/p/3961159.html

http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值