类和接口
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数组则使用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是高地址存低位,低地址存高