您的位置:首页 > 编程语言 > Java开发

String 源码简析

2017-08-25 20:21 330 查看


String源码简析(未完成,待本周末更新)

摘要: String是Java中的常用类,本文对String源码做简要分析。


类和接口

String类被定义成
public final class
,所以String类无法被继承。

String类实现了Serializabel、Comparabe、CharSequence三个接口,分别对应着序列化、排序、字符串处理三个方面的功能。


类属性

String类底层有固定长度的字符数组组成,用hash的方法缓存字符串,含有一个序列化ID以及一个用于序列化的ObjectStreamField类,这个类我们会单独拿出一篇文章来讲。
private final char value[];
private int hash;
private static final long seriaVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];



类方法


构造方法

String构造数据的构造方法有很多实现方法。


默认构造方法

public String();


新建一个单个字符的char数组。常见于
String str = new String();



带参构造方法

public String(String original);


String类型的传参直接赋值
public String(char value[]);


char数组则使
4000
用Arrays来直接拷贝,当然,可以在传参的时候,可以再加上位移量和长度(数量),详见String的源码
public String(int[] codePoint, int offset, int count);
public String(byte ascii[], int hibyte, int offset, int count);
public String(byte bytes[], Charset charset);
public String(byte bytes[], int offset, int length);
public String(byte bytes[]);


一些byte及编码类型的传参不再赘述。
public String(StringBuffer buffer);
public String(StringBuilder builder);


JDK1.5之后,String可以通过StringBuffer和StringBuilder调用Arrays.copyOf()来初始化String。其中,StringBuffer在调用的时候,会加锁以保证线程安全。


一般方法

字符操作
length()
、 
isEmpty()
、 
charAt()
、 
codePointAt()
、 
codePointBefore()
、 
codePointCount()
、 
getBytes()
 方法功能同名。
public boolean equals(Object anObject);
public boolean equalsIgnoreCase(String anotherString); // 大小写不敏感

String是final对象,所以在写equals方法时,是在比较String的各位char数值。
String是不可变对象,所以该方法没有涉及线程相关的设计。
public boolean contentEquals(StringBuffer sb);
public boolean contentEquals(CharSequence cs);

equals()方法只能比较String,而contentEquals的比较类型更多
contentEquals针对StringBuffer、StringBuilder、String、Charsequence有着不同的比较方法。
StringBuffer多加了一个
synchronnized
来保证线程安全。
contentEquals功能同名,只比较内容,而忽略类型。
public int compareTo(String anotherString);


按字典序列比较内容,返回不同字符处的距离或不同字符串长度,相等返回0


内部类 CaseInsensitiveComparator

我们发现内部类CaseInsensitiveComparator的compare比较方法为了实现大小写不敏感,把字符分别
toUppperCase
toLowerCase
比较了一遍,


一般方法

public boolean regionMatches(int toffset, String other, int ooffset,int len);
public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len);


比较两个字符串从某处开始的特定长度的字串是否相等。
public String concat(String str);


concact是拼接函数,其中为了设计char数组的拷贝,使用了传入String对象的getChars()方法。
void getChars(char dst[], int dstBegin) {
System.arraycopy(value, 0, dst, dstBegin, value.length);
}


在这个函数中,使用了System的arraycopy方法,把当前字符串拷贝到传入字符串数组的结尾。

最后,concat返回一个新的String对象
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;
}


replace方法用于返回一个替换字符串,但是这个方法重复执行了部分的循环操作。第一个循环用于找到第一个匹配的字符的位置,之后,再从头到此位置进行替换,最后从该位置之后再判断。这样做的目的是什么呢?
Java是高地址存低位,低地址存高
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息