为什么String类是不可变的
public final class String{
private final char[] value;
}
由以上String类的源码可以看出,String类内部使用字符数组char[]
来存储字符串(Java 9后修改为byte[]
字节数组),而且数组被final
修饰且为私有的,String类没有提供修改该字符串方法,
以及由于String类被final
修饰所以无法继承,避免子类破坏String不可变。
String与StringBuilder、StringBuffer的比较
- String与StringBuffer是线程安全的,而StringBuilder不是线程安全的;
- 只要String是不可变的,StringBuilder和StringBuffer都可以修改;
- 性能:StringBuilder>StringBuffer>String
- 用途:
- 少量数据:String
- 大量数据单线程: StringBuilder
- 大量数据多线程: StringBuffer
字符串 + 拼接
字符串+拼接实际上调用的是StringBuilder
的append
方法,再通过toString()得到String,这样如果循环内使用+拼接字符串的话会重复创建StringBuilder,可以直接使用StringBuiler避免这个问题。(JDK9之后已经解决了这个问题)
字符常量池
字符常量池是JVM给字符串专门开辟的区域,可以避免字符串重复创建,常量池在堆中。
字符串常量池实际上是由HashTable
实现的,保存的字符串(key)和对字符串对象的引用(value),字符串对象的引用则指向堆中的字符串对象。