目录
String源码学习
string类的定义
string类的变量
string类的构造方法
length方法
isEmpty方法
charAt方法
equals方法
equalsIgnoreCase方法
compareTo方法
startWith方法
public final class String
implements java.io.Serializable, Comparable
(1)string类是被final修饰的,说明该类不能被继承。
(2)string类被设计成final类型:
1)安全。string类被设计成final类型,表示不可被继承,不可继承就不会被修改,从而避免了因为继承而引起的安全隐患。
2)效率。string类在程序中出现的频率比较高,如果是为了降低安全隐患,在它每次出现时都用final来修饰,这样会降低程序的执行效率,所以将其设置为final类型,从而提高了效率。
(3)string类实现了serializable(可序列化)、comparable(用到compareto方法)、charsequence(charsequence与string都可以用来定义字符串,charsequence的值是可读可写序列,string的值是只读序列)三个接口。
//用于存储字符的字符数组,值不可更改
private final char value[];
//该字符串的hash code,默认值为0
private int hash; // Default to 0
private static final long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
(1)string类是char[]数组存储的数据,数组用final修饰,其为常量,只能被赋值一次。
(1)无参数的构造方法。
public String() {
this.value = "".value;
}
(2)参数为string类型的构造方法。
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
(3)参数为char数组的构造方法
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
(4)参数为char数组的构造方法
从char数组的offset位置开始,截取count个字符,赋值给string的value。
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);
}
public int length() {
return value.length;
}
length方法返回value数组的长度。
public boolean isEmpty() {
return value.length == 0;
}
isEmpty方法判断value数组长度是否为0。
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
charAt方法返回value数组中下标为index的元素。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
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;
}
string类的equals方法:
(1)先是判断两个字符串是否是对同一个对象的引用,即两者在内存中的地址是否相同。
(2)判断是否属于string类型,不是的话,则返回false。
(3)判断两个字符串的长度是否相等,不相等返回false。
(4)逐次判断两个字符串中的单个字符是否相等,不相等返回false,否则继续。
public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true
: (anotherString != null)
&& (anotherString.value.length == value.length)
&& regionMatches(true, 0, anotherString, 0, value.length);
}
public boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len) {
char ta[] = value;
int to = toffset;
char pa[] = other.value;
int po = ooffset;
// Note: toffset, ooffset, or len might be near -1>>>1.
if ((ooffset < 0) || (toffset < 0)
|| (toffset > (long)value.length - len)
|| (ooffset > (long)other.value.length - len)) {
return false;
}
while (len-- > 0) {
char c1 = ta[to++];
char c2 = pa[po++];
if (c1 == c2) {
continue;
}
if (ignoreCase) {
// If characters don't match but case may be ignored,
// try converting both characters to uppercase.
// If the results match, then the comparison scan should
// continue.
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
continue;
}
// Unfortunately, conversion to uppercase does not work properly
// for the Georgian alphabet, which has strange rules about case
// conversion. So we need to make one last check before
// exiting.
if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
continue;
}
}
return false;
}
return true;
}
equalsIgnoreCase方法是string类的忽略大小写的相等比较。
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
}
public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = toffset;
char pa[] = prefix.value;
int po = 0;
int pc = prefix.value.length;
// Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > value.length - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}