String这个类的使用频率之高,可以说无处不在,源码必读,从属性,构造器,常用方法等来阅读,对于过时的不再阅读,该类直接实现了java.io.Serializable, Comparable, CharSequence 接口
属性
在本类中定义的属性很少
private final char value[];//用于存储字符
private int hash;//为字符串缓存散列代码,默认为0
private static final long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];//String对象可以写到ObjectStream中
构造器
String的构造器很多,参数基本上就那几个组合,最基本的String ,char[],byte[],StringBuffer,StringBuilder要么加上offset和count,在要么加上编码。
//1.无参数的,空串一个
public String() {
this.value = "".value;
}
//2.一个参数的构造器主要是
//传入字符串,将值赋给value,给定hash值
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
//传入字符数组,将值复制到value
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
//传入字节数组,调用另一个构造器
public String(byte bytes[]) {
this(bytes, 0, bytes.length);
}
//传入StringBuffer,将值复制到value,这里加上了线程同步
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
//传入StringBuilder ,将值复制到value
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
//3.两个参数的构造器
//传入byte数组和一个字符编码名称,调用另一个构造器。因为该编码是自定义的,可能不存在,所以抛出异常
public String(byte bytes[], String charsetName)
throws UnsupportedEncodingException {
this(bytes, 0, bytes.length, charsetName);
}
//传入字节数组和编码,调用另一个构造器,
public String(byte bytes[], Charset charset) {
this(bytes, 0, bytes.length, charset);
}
//缺省的构造器,传入字符数组和boolean,因为String不能被继承,所以相对于私有的。
String(char[] value, boolean share) {
this.value = value;
}
//4.三个参数的构造器(部分)
//传入char数组,两个int,offset是起始位置,count是长度(指取值的长度)
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;
}
}
//起始位置大于到取值的位置抛出异常
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
//传入字节数组,两个int调用StringCoding中的方法
public String(byte bytes[], int offset, int length) {
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(bytes, offset, length);
}
//5.四个参数的,在三个之上再加编码,Charset类型或者String型
简单测试
@Test
public void ss(){
Charset c=Charset.forName("utf-8");//定义一个编码
char[] cc=new char[]{'a','b','c','哈'};//定义字符数组
byte[] b=new byte[]{'f','1','s','3'};//定义字节数组
int offset=1;//定义起始位置
int count=2;//定义长度
String s1=new String(cc);
String s2=new String(b,c);
String s3=new String(cc,offset,count);
String s4=new String(b,offset,count,c);
System.out.println("s1:"+s1+"\n"+"s2:"+s2+"\n"+"s3:"+s3+"\n"+"s4:"+s4);
}
结果与分析
控制台打印如下
s1:abc哈
s2:f1s3
s3:bc
s4:1s
只有了解了他的构造器才能更灵活的去使用,尤其注意传入两个int是,如上是指重索引位置为1的地方开始取值,取两个长度。