概述
String類型是java語言中最常用的類型,有很多特性。
- 不可繼承性
- 不可改變性
- 引用類型
- 常量池
String的字符串常量,是在編譯器生成,維護到常量池中;運行時方法區中。
String a = "Hello";//常量池
String b = "World";//常量池
String c = "HelloWorld";//常量池
String d = "Hello" + "World";//常量池
String e = a + b;//常量池
String f = new String("HelloWold");//在堆中
所以
- c、d、e 是相同的地址,而 f 和c、d、e是不相同。
- String創建字面量首先是在常量池中尋找是否有相同,沒有才在常量池中創建。
- native intern() 是本地方法用於將堆中的String對象,序列化到常量池中存儲。
源碼
一、屬性
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** 字符串數組 */
private final char value[];
/** 偏移量 */
private final int offset;
/** 字符串長度 */
private final int count;
/** hash值 */
private int hash; // Default to 0
}
1、String的存儲其實是維護了一個 Char[] 數組,用於存儲字符串,都是被 final 修飾,所以也體現了String的不可改變性。
2、String類被 final 修飾,表示該類不可以被繼承。
常用構造方法
1、無參構造函數
public String() {
this.offset = 0;
this.count = 0;
this.value = new char[0];
}
2、String
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
3、字符數組
public String(char value[]) {
this.offset = 0;
this.count = value.length;
this.value = StringValue.from(value);
}
4、指定字符碼
public String(byte bytes[], String charsetName)
throws UnsupportedEncodingException
{
this(bytes, 0, bytes.length, charsetName);
}
5、字節數組
public String(byte bytes[]) {
this(bytes, 0, bytes.length);
}
6、StringBuffer、StringBuilder
public String(StringBuffer buffer) {
String result = buffer.toString();//調用應用類型的toString 方法
this.value = result.value;
this.count = result.count;
this.offset = result.offset;
}
public String(StringBuilder builder) {
String result = builder.toString();/調用應用類型的toString 方法
this.value = result.value;
this.count = result.count;
this.offset = result.offset;
}
equals和hashCode、toString
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
public String toString() {
return this;
}
常用方法列表
1、length()
public int length() {
return count;
}
2、isEmpty()
public boolean isEmpty() {
return count == 0;
}
3、charAt(int index)
public char charAt(int index) {
if ((index < 0) || (index >= count)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}
4、getBytes()
public byte[] getBytes() {
return StringCoding.encode(value, offset, count);
}
5、equalsIgnoreCase(String anotherString)
public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true :
(anotherString != null) && (anotherString.count == count) &&
regionMatches(true, 0, anotherString, 0, count);
}
6、compareTo(String anotherString)
public int compareTo(String anotherString) {
int len1 = count;
int len2 = anotherString.count;
int n = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
if (i == j) {
int k = i;
int lim = n + i;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
} else {
while (n-- != 0) {
char c1 = v1[i++];
char c2 = v2[j++];
if (c1 != c2) {
return c1 - c2;
}
}
}
return len1 - len2;
}
7、istartsWith(String prefix)
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
}
8、endsWith(String suffix)
public boolean endsWith(String suffix) {
return startsWith(suffix, count - suffix.count);
}
9、indexOf(String str)
public int indexOf(String str) {
return indexOf(str, 0);
}
10、substring(int beginIndex)
public String substring(int beginIndex) {
return substring(beginIndex, count);
}
11、replace(char oldChar, char newChar)
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = count;
int i = -1;
char[] val = value; /* avoid getfield opcode */
int off = offset; /* avoid getfield opcode */
while (++i < len) {
if (val[off + i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0 ; j < i ; j++) {
buf[j] = val[off+j];
}
while (i < len) {
char c = val[off + i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(0, len, buf);
}
}
return this;
}
12、boolean matches(String regex)
public boolean matches(String regex) {
return Pattern.matches(regex, this);
}
13、*** String[] split(String regex)***
public String[] split(String regex) {
return split(regex, 0);
}
14、String toLowerCase()
public String toLowerCase() {
return toLowerCase(Locale.getDefault());
}
15、String toUpperCase()
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
16、String trim()
public String trim() {
int len = count;
int st = 0;
int off = offset; /* avoid getfield opcode */
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[off + st] <= ' ')) {
st++;
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < count)) ? substring(st, len) : this;
}
17、String format(String format, Object … args)
public static String format(String format, Object ... args) {
return new Formatter().format(format, args).toString();
}
18、String valueOf(Object obj)
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
public static String valueOf(int i) {
return Integer.toString(i, 10);
}