工作三年了,用了三年的JAVA,突然发现竟然没有好好的看下JDK的源码,整天用着的String,只是大概知道怎么回事,其中的实现逻辑却是一头雾水。
知耻而后勇,加油!!!
java.lang.String
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { }
String不属于基本的数据类型,由于是final类型不能被继承,可以序列化。
/** The value is used for character storage. */ private final char value[];
使用final类型的字符数组存储字符串内容,String初始化后就不能被改变。
String temp = "abc"; temp = "bcd";
这里并不是对temp的修改,而是重新指向新的字符串。
/** Cache the hash code for the string */ private int hash; // Default to 0
指定缓存字符串的hash code的值,默认为0
/** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L;
String实现了java.io.Serializable接口,支持序列化操作。
注:序列化是为了存储整个对象,对象序列化的最主要的用处就是在传递和保存对象(object)的时候,保证对象的完整性和可传递性。
譬如通过网络传输,或者把一个对象保存成一个文件的时候,要实现序列化接口。
源码中提供了很多种构造方法,有采用字节数组来构造,有采用StringBuffer和StringBuilder来构造等。
public String(byte bytes[]) { this(bytes, 0, bytes.length); } public String(StringBuffer buffer) { synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } } public String(StringBuilder builder) { this.value = Arrays.copyOf(builder.getValue(), builder.length()); }
其中有一种特殊的构造方法:
/* * Package private constructor which shares value array for speed. * this constructor is always expected to be called with share==true. * a separate constructor is needed because we already have a public * String(char[]) constructor that makes a copy of the given char[]. */ String(char[] value, boolean share) { // assert share : "unshared not supported"; this.value = value; }
受保护的构造方法,提供两个参数,其中share参数未使用,对比前一个构造方法
public String(char value[]) { this.value = Arrays.copyOf(value, value.length); }
后一种采用Arrays的copyOf方法将value中的内容逐一复制到String当中,而前一种直接采用引用赋值的方式,共享一个数组。
这种特殊的构造方法优点:性能好,共享数组【节约内存】。
// 返回字符串的长度 public int length() { return value.length; } // 字符串是否为空 public boolean isEmpty() { return value.length == 0; } // 字符串目标位置的字符 public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } // 返回指定索引处的字符 public int codePointAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return Character.codePointAtImpl(value, index, value.length); } // 返回指定索引之前的字符 public int codePointBefore(int index) { int i = index - 1; if ((i < 0) || (i >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return Character.codePointBeforeImpl(value, index, 0); } // 返回此 String 的指定文本范围中的 Unicode 代码点数 public int codePointCount(int beginIndex, int endIndex) { if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) { throw new IndexOutOfBoundsException(); } return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex); }
第二部分,介绍String中一些常用方法的重载和区别:
如:replace, replaceFirst, replaceAll区别,valueOf重载