Java String为什么是不可变类,StringBuffer与StringBuilder区别

熟悉Java的都知道String类是不可变,但String类为什么设计成不可变类,如何做到不可变没有仔细想过。
String为什么设计成不可变类?
1.符合Java字符串池的设计方式。

[java] view plain copy
String s1=”abc”;
String s2=”abc”;
Java通过字符串池的设计方式节省内存空间,如上面一段代码只会生成一个对象放在常量池当中。s1和s2都指向这个对象,如果String类可变,通过s1这个引用就可以修改这个对象,那其他引用就会受影响。

2.安全性。
JDK提供的众多API当中,大多的参数都是String类型,如类加载函数,数据库的连接,Sql语句,Socket的参数等。如果String类可以被修改就会造成安全漏洞。而且多线程情况下,String类数据也可以保护数据不被其他线程修改。
String怎么实现不可变?
[java] view plain copy
public final class String
implements java.io.Serializable, Comparable, CharSequence {
private final char value[];

从String类的源码中可以看到,String是通过char value[]保存字符的。而且声明为private final,并且不提供我们写value的接口。所以String类不能够修改。

(其实String类并不是不能修改,可以通过java的反射机制,获取到string对象的class对象,把value属性private修改为可访问类型,然后就可以直接访问对象value属性了)

StringBuffer和StringBuilder的区别
StringBUffer和StringBuilder都是可变的字符串类,StringBuffer和StringBuilder类的区别也在于StringBuffer是线程安全的,很多方法都有synchronized关键字,如下代码。StringBuilder不是线程安全的,所以一般情况下StringBuilder的性能要好。
[java] view plain copy
//StringBuffer类的源码
ublic synchronized void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}

/**
* @since 1.5
*/
public synchronized void trimToSize() {
super.trimToSize();
}

/**
* @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length()
*/
public synchronized void setLength(int newLength) {
super.setLength(newLength);
}

/**
* @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length()
*/
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值