一、签名:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence |
String不能被继承,
实现了Serializable:可被序列化。
实现了Comparable:可以比较,排序,
实现了CharSequence:值是可读序列。
二、成员变量:
private final char value[]; // 存储字符。 |
private int hash; // 缓存字符串的hash值。 |
Private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamFiled[0]; // 字符串类被指定转化序列化流协议中。 |
/** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L; |
Value是final的,所以String一旦定义之后,就不可变的。
三、构造函数:
四、常用方法:
由于String中重载的方法太多了,所以就只写方法名了。
1. getBytes:
public byte[] getBytes() { return StringCoding.encode(value, 0, value.length); } |
以上面的这个方法为例:它交给了StringCoding.encode去获取bytes。然而StringEncoder去调用了StringEncoder的相应方法获取bytes、
2. equals
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) { //不错的编码风格。比for要好一点? if (v1[i] != v2[i]) return false; i++; } return true; } } return false; } |
3. equalsIgnoreCase:
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; } |
在regionMatches中首先对传入的参数,进行合法性判断。然后取出每一个字符,比较一下,相同就下个字符,不同,都转换成大写,比较一次,如果相同就比较下一个字符,如果不相同就都转化成小写在比较一下。解释是说:有时候,转大写不一定每次都会正确。
4. startsWith:
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; } |
5. endsWith
public boolean endsWith(String suffix) { return startsWith(suffix, value.length - suffix.value.length); } |
6. 重点来了:hashCode
public int hashCode() { int h = hash; ///先获取缓存中的hash值。 if (h == 0 && value.length > 0) { char val[] = value;
for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; // hash值算法。31 } hash = h; } return h; } |
7. 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) { break; } } if (i < len) { char buf[] = new char[len]; for (int j = 0; j < i; j++) { 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; } |