String源码理解(jdk1.8)
string是被final修饰的类
public final class String
实现了
Serializable
,Comparable<String>
,CharSequence
这三个接口,Comparable
接口有compareTo(String s)
方法,CharSequence
接口有length()
,charAt(int index)
,subSequence(int start,int end)
方法。
构造方法
- String(char value[], int offset, int count)
– 这个方法调用了Arrays.copyOfRange(value[],from,to)
这个方法,这个方法最后还是调用了System.arraycopy
这个方法,来复制数组
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= value.length) {
this.value = "".value;
return;
}
}
// 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);
}
属性
- 底层使用字符数组实现的
private final char value[];
方法
equals
- 最长用到的equals方法,重写了object的equals方法:
public boolean equals(Object anObject) {
//判断是否为同一个引用对象
if (this == anObject) {
return true;
}
//判断anObject是否是String类以及其子类的实例
if (anObject instanceof String) {
转换类型
String anotherString = (String)anObject;
int n = value.length;
// 判断长度是否相等
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
length()
- 因为数组被private修饰,外部只能通过方法访问
public int length() {
return value.length;
}
charAt(int index)
- 返回下标所对应的字符
public char charAt(int index) {
// 判断下标是否越界
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
trim()
- 去掉字符串首位空格
– 注意:调用这个方法,原来的字符串并没有发生改变,这个方法返回的字符串才是被改变后的字符串
// 如果首尾没有空格则返回原来的数组,有则调用substring方法
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
substring()
- 作用:根据下标截取字符串;一个参数的方法是截取从下标开始到末尾结束的字符,两个参数的方法是截取从前一个下标截取到后一个下标的位置的字符;
– 这个方法有两种形式的,一个是只有一个int
类型参数,一个有两个int
类型参数
– 最后会判断是否调用构造方法,而构造方法最后调用Arrays.copyOfRange
这个方法,最后还是调用System.arraycopy
这个方法
//一个参数
int subLen = value.length - beginIndex;
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
//两个参数
int subLen = endIndex - beginIndex;
return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen);
split()
作用:将字符串根据传入的参数分割;一个参数时默认全部分割,两个参数时,前一个是指分割条件,后一个参数是分割的份数;
一个参数的方法最后还是调用了两个参数的方法,只是把后边的参数默认为0了
public String[] split(String regex) {
return split(regex, 0);
}
总结
String类中的方法中只要是返回的String类型,则返回的结果都是新的String对象,除开一些特殊的例子
final修饰的类是不可以被继承或修改的,也就是string类是不可以被继承的;
- 底层采用final修饰的字符串数组
String类封装了一系列的对字符串进行操作的方法
- 未完,待续。。。。。。