熟悉Java的都知道String类是不可变,但String类为什么设计成不可变类,如何做到不可变没有仔细想过。

String为什么设计成不可变类?
1.符合Java字符串池的设计方式。     String s1="abc"; String s2="abc";     
Java通过字符串池的设计方式节省内存空间,如上面
一段代码只会生成一个对象放在常量池当中。s1和s2都指向这个对象,如果String类可变,通过s1这个引用就可以修改这个对象,那其他引用就会受影响。
2.安全性。      
JDK提供的众多API当中,大多的参数都是String类型,如类加载函数,数据库的连接,Sql语句,Socket的参数等。如果String类可以被修改就会造成安全漏洞。而且多线程情况下,String类数据也可以保护数据不被其他线程修改。
String怎么实现不可变?
public final class String implements java.io.Serializable, Comparable<String>,
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的性能要好。
//StringBuffer类的源码 public 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]; }

技术
©2019-2020 Toolsou All rights reserved,
ElementUI中获取select 的label值迷宫的最短路径之BFS算法(python实现)指定位置输出字符串(详细解析)人工智能算法总结实验11-1-6 指定位置输出字符串 (20 分)SpringDataJPA的Repository理解python 动态规划求解单源最短路径vue使用THREE.js创建一个可以控制的立方体python读取、写入txt文本内容 项目跟了一年,客户最后说不做了