JDK源码学习--String篇(-)基础篇
工作三年了,用了三年的JAVA,突然发现竟然没有好好的看下JDK的源码,整天用着的String,只是大概知道怎么回事,其中的实现逻辑却是一头雾水。
知耻而后勇,加油!!!
java.lang.String
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
}
String不属于基本的数据类型,由于 final类型不能被继承,可以序列化。
/** The value is used for character storage. */
private final char value[];
使用final类型的字符数组存储字符串内容,String初始化后就不能被改变。
String temp = "abc";
temp = "bcd";
这里并不是对temp的修改,而是重新指向新的字符串。
/** Cache the hash code for the string */
private int hash; // Default to 0
指定缓存字符串的hash code的值,默认为0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
String实现了java.io.Serializable接口,支持序列化操作。
注:序列化是为了存储整个对象,对象序列化的最主要的用处就是在传递和保存对象(object)的时候,保证对象的完整性和可传递性。
譬如通过网络传输,或者把一个对象保存成一个文件的时候,要实现序列化接口。
源码中提供了很多种构造方法,有采用字节数组来构造,有采用StringBuffer和StringBuilder来构造等。
public String(byte bytes[]) {
this(bytes, 0, bytes.length);
}
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
其中有一种特殊的构造方法:
/*
* Package private constructor which shares value array for speed.
* this constructor is always expected to be called with share==true.
* a separate constructor is needed because we already have a public
* String(char[]) constructor that makes a copy of the given char[].
*/
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}
受保护的构造方法,提供两个参数,其中share参数未使用,对比前一个构造方法
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
后一种采用Arrays的copyOf方法将value中的内容逐一复制到String当中,而前一种直接采用引用赋值的方式,共享一个数组。
这种特殊的构造方法优点:性能好,共享数组【节约内存】。
// 返回字符串的长度
public int length() {
return value.length;
}
// 字符串是否为空
public boolean isEmpty() {
return value.length == 0;
}
// 字符串目标位置的字符
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
// 返回指定索引处的字符
public int codePointAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointAtImpl(value, index, value.length);
}
// 返回指定索引之前的字符
public int codePointBefore(int index) {
int i = index - 1;
if ((i < 0) || (i >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointBeforeImpl(value, index, 0);
}
// 返回此 String 的指定文本范围中的 Unicode 代码点数
public int codePointCount(int beginIndex, int endIndex) {
if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) {
throw new IndexOutOfBoundsException();
}
return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
}
第二部分,介绍String中一些常用方法的重载和区别:
如:replace, replaceFirst, replaceAll区别,valueOf重载