JDK中String类的源码分析(一)
1、String类是final的,不允许被继承
1 /** The value is used for character storage. */ 2 private final char value[]; 3 4 /** Cache the hash code for the string */ 5 private int hash; // Default to 0
String类的内部就是维护了一个char数组;
2、构造方法,只需要看两个接受char数组的构造方法
1 public String(char value[]) { 2 this.value = Arrays.copyOf(value, value.length); 3 } 4 5 public String(char value[], int offset, int count) { 6 if (offset < 0) { 7 throw new StringIndexOutOfBoundsException(offset); 8 } 9 if (count < 0) { 10 throw new StringIndexOutOfBoundsException(count); 11 } 12 // Note: offset or count might be near -1>>>1. 13 if (offset > value.length - count) { 14 throw new StringIndexOutOfBoundsException(offset + count); 15 } 16 this.value = Arrays.copyOfRange(value, offset, offset+count); 17 }
这两个构造方法都用到了,Arrays工具类的copyOf方法,在这两个方法里面都调用了System.arraycopy方法;
因为System.arraycopy是一个系统本地方法,所以这个方法的效率很高,所以在构造String的时候效率也很高;
3、常用的length,charAt方法
通过第一条,很容易知道,这两个方法,实际上就是在操作char数组
1 public int length() { 2 return value.length; 3 } 4 5 public boolean isEmpty() { 6 return value.length == 0; 7 } 8 9 public char charAt(int index) { 10 if ((index < 0) || (index >= value.length)) { 11 throw new StringIndexOutOfBoundsException(index); 12 } 13 return value[index]; 14 }
4、getBytes方法
调用了StringCoding.encode方法,encode方法调用另外一个重载的方法
1 static byte[] encode(char[] ca, int off, int len) { 2 String csn = Charset.defaultCharset().name(); 3 try { 4 // use charset name encode() variant which provides caching. 5 return encode(csn, ca, off, len); 6 } catch (UnsupportedEncodingException x) { 7 warnUnsupportedCharset(csn); 8 } 9 try { 10 return encode("ISO-8859-1", ca, off, len); 11 } catch (UnsupportedEncodingException x) { 12 // If this code is hit during VM initialization, MessageUtils is 13 // the only way we will be able to get any kind of error message. 14 MessageUtils.err("ISO-8859-1 charset not available: " 15 + x.toString()); 16 // If we can not find ISO-8859-1 (a required encoding) then things 17 // are seriously wrong with the installation. 18 System.exit(1); 19 return null; 20 } 21 }
得到一个字节数组,是由ISO-8859-1编码得到,当然也可以用其他编码
5、compareTo方法
因为String实现了Comparable接口,所、所以必须实现compareTo方法
1 public int compareTo(String anotherString) { 2 int len1 = value.length; 3 int len2 = anotherString.value.length; 4 int lim = Math.min(len1, len2); 5 char v1[] = value; 6 char v2[] = anotherString.value; 7 8 int k = 0; 9 while (k < lim) { 10 char c1 = v1[k]; 11 char c2 = v2[k]; 12 if (c1 != c2) { 13 return c1 - c2; 14 } 15 k++; 16 } 17 return len1 - len2; 18 }
其实是遍历的比较两个数组