Java String类
String类源码如下
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
//...
}
注:Java9之后,String类实现改用byte数组存储字符串private final byte[] value
- String类被final修饰,不可被继承,成员方法默认final
- String类实现了Serializable、CharSequence、 Comparable接口。
- String类的值是通过char数组存储的,并且char数组被private和final修饰,字符串一旦创建就不能再修改。
replace()方法
sub、concat还是replace操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象。
final修饰String类
final修饰类不可被继承
- 安全性
- 字符串不可变,保证多线程安全,同一个字符串实例可以被多个线程共享。
- 网络URL、文件路径、反射机制等需要String参数,确保安全
- 效率
- 字符串不变保证hash码唯一性,放心缓存,不必每次计算新哈希码,性能优化手段。
- 字符串不可变,字符串池有可能实现。 字符串常量池是Java堆内存中特殊存储区域,当创建一个String对象,若已存在,则引用已存在对象。
字符串常量池
JVM为提升性能和减少内存开销,实例化字符串的时候使用字符串常量池进行优化。池化思想。字符串常量池保存着所有字符串字面量,这些字面量在编译时期就确定。String 的 intern() 方法在运行过程将字符串添加到 String Pool 中。
JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。
String a = new String("abc")
创建一个或两个对象,字符串常量池一个(取决于之前"abc"是否被使用),堆中创建一个。
字符串拼接
String +=底层使用StringBuilder,先初始化StringBuilder对象,再使用append()方法,然后toString()返回结果。
StringBuilder & StringBuffer
StringBuffer和StringBuilder继承自AbstractStringBuilder
类。StringBuffer方法被synchronized
修饰,是线程安全。
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
参考:阿里技术、JavaGuide