竹笋

首页 » 问答 » 问答 » 必知必会StringStringBui
TUhjnbcbe - 2024/5/20 5:15:00
自媒体求职招聘QQ群 http://www.jpm.cn/article-124253-1.html

必知必会:String、StringBuilder及StringBuffer区别?

问题背景

String、StringBuilder及StringBuffer这几个类在日常工作可谓无时无刻不在使用,他们之间的区别也是面试或者工作中的必备知识点。梳理一波,查漏补缺。

String特性梳理

(1)实现了序列化Serializable,Comparable以及CharSequence字符序列接口

String是Java字符串对象,底层是基于char字符数组,使用了final修饰类,表示最终类,不能被继承和修改,线程安全~

(2)每一次对String声明的对象的内容进行修改,得到的都是另外一个新的字符串常量对象,如果字符串常量池中已经存在该字符串常量对象,则不会再创建~

(3)JDK1.8,字符串常量拼接还被自动优化成了StringBuilder,例如:

Strings1=“first”;

Strings2=“second”;

Strings3=s1+s2;

//先javac编译java源文件得到Class,再经过javap-cClassName反编译查看汇编指令发现,发现s1+s2等价于

Strings4=newStringBuffer().append(s1).append(s2).toString();

如下图所示:

(4)String重写了Object类中的equals、hashCode方法,重写后equals方法比较了字符串的每一个字符,而重写hashCode方法则是由字符串的每一个字符计算出字符串的hashCode值~

(5)String常用API

2.StringBuilder特性梳理

(1)底层继承了AbstractStringBuilder,实现了Serializable、CharSequence接口

(2)底层基于char字符数组,可以修改操作对象,非线程安全

(3)StringBuilder初始化时默认字节数组初始化容量大小为16,当容量大于当前字节数组容量时会自动进行1倍扩容再加2,每次扩容都会开辟新空间,并且进行新老字符数组的复制:源码底层通过调用System的一个native本地方法arraycopy实现新老字符数组的复制,该native方法底层会直接操作内存,比一般的for循环遍历复制数组的效率要快很多;

(4)如果要操作拼接字符串,并且拼接的字符串很长,又没有给StringBuilder指定合适的初始化容量大小,可能会导致底层的字符数组进行多次扩容,多次申请内存空间来完成新老字符数组的复制,性能开销比较大;

(5)StringBuilder常用API

3.StringBuffer特性梳理

StringBuffer底层实现与StringBuffer最大的区别在于方法使用了synchronized关键字同步,因此是线程安全的,StringBuilder非线程安全!

总结:String、StringBuilder及StringBuffer的区别是什么?

(1)String使用final修饰,表示最终类,不可继承和修改,线程安全;

(2)而StringBuilder和StringBuffer都是可修改对象,StringBuffer使用synchronized同步修饰方法,线程安全,StringBuilder非线程安全;

(3)String在JDK1.8时字符串常量拼接被自动优化成了StringBuiler。

1
查看完整版本: 必知必会StringStringBui