String 源码学习笔记
对于java程序员来说,String类是在熟悉不过了,但你真的了解它吗?常用构造器有哪些?intern()
方法是干什么的?字符串拼接“+”号是如何实现的?我们通过源码一一解答。
本章String源码使用java1.8版本
String
以下几个特性决定它是不可变的
1、`String`是`final`类,不可继承。
2、字符数组成员变量`value`使用`final`修饰,也就是常量,常量一大好处就是线程安全,所以`String`不需要考虑线程安全问题。
当然如果通过反射还是可以修改
value
常量值的,这时候会发现如果字符串是在常量池里,那么这个常量池字符串将会被修改成其他值。
3、成员变量`value`字符数组必须独有,其他程序(不包括String类和反射)不可操作`value`字符数组
String构造器
默认构造器String()
这个构造器基本上不使用,反正博主是没见过使用它的。
这个很简单,看一下源码就什么都明白了
public String() {
this.value = new char[0];
}
实际上就是个长度等于0的字符数组,其实就是空字符串""
,运行以下案例就什么都明白了
String empty = "";
String str = new String();
System.out.println(empty == (str));//false
System.out.println(empty == (str).intern());//true 如果不明白是什么后面章节将介绍
System.out.println(empty.equals(str));//true
字符串构造器String(String original)
使用的也比较少
其实这个构造器就是个克隆的过程,但String是不可变的,所以克隆也是没有多大必要。
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
通过看源码也是一目了然,不在做过多讲解。
字符数组构造器String(char value[])
字符数组构造器有三个重载:
第一种:
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
传入一个字符数组,将该数组拷贝一份复制给value
,其实这样做就是为了保证String
不可变性,介绍不拷贝的话,字符数组中的元素就可以发生变化,如下代码:string
成员变量value
第一元素就会被修改为'1'
,这样就破坏了String
的不可变性。第三种字符数组构造器就是这样实现的。
char[] value = {
'a','b','c'};
String string = new String(value);
value[0] = '1';
第二种:
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {