对String类的讨论已经是老生常谈了,最权威的莫过于源码,今天就来看下String源码。基于JDK1.8。
支持原创,转载请注明出处。
继承关系
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
成员变量
private final char value[]; //private, final修饰确保不会被外界引用,且所有操作不会修改数组的值,这是String常量性质的保证
private int hash; // Default to 0
构造方法
public String() {
this.value = new char[0];
}
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
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) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
构造函数都很直观。
charAt方法
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
很直观,直接返回下标对应的字符。
substring方法
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen); //创建一个新的String对象
}
该方法,首先检查参数是否合法,若合法,则创建一个新的String对象,期间伴随着拷贝操作。
replace方法
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) { //新老字符不相等直接方法当前对象
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
while (++i < len) {
if (val[i] == oldChar) { //寻找第一个oldChar
break;
}
}
if (i < len) { //存在oldChar
char buf[] = new char[len];
for (int j = 0; j < i; j++) { //原封不动拷贝i之前的字符
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c; //用新字符替换旧字符
i++;
}
return new String(buf, true); //创建新的字符串,并返回
}
}
return this;
}
该方法寻找第一个oldChar下标i,如果存在oldChar,则新建一个字符数组buf,拷贝i之前的字符到新字符数组,i之后用新字符替换旧字符。用buf新建String对象,并返回。
总结
String的常量性质来源于private final char value[]
,并且所有操作中都不会直接修改value这个数组。
支持原创,转载请注明出处。
github:https://github.com/gatsbydhn
网友评论