String 類代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作爲此類的實例實現。字符串是常量;它們的值在創建之後不能更改。字符串緩衝區支持可變的字符串。因爲 String 對象是不可變的,所以可以共享。
java中對字符串的操作是非常便捷的,因爲java提供了許多針對字符串操作的方法。一下是一些常用方法:
更多方法請查看java JDK API文檔。
關於幾個方法的要點
equals方法
String類中複寫了Object類的equals方法:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
可以看到當且僅當參數不爲 null,並且是與此對象表示相同字符序列的 String 對象時,結果才爲 true。換句話說就是隻有當兩個引用指向同一個對象時或兩個不同的String對象表示相同的字符序列時,返回true。而 == 比較的是兩個引用所指向的對象的地址是否相同,也就是兩個引用是否指向同一個引用。下面通過一個小例子說明。
public static void main(String[] args) {
// TODO Auto-generated method stub
String a = "abc";
String b = "abc";
String c = new String("123");
String d = new String("123");
System.out.println("a == b :"+(a == b));
System.out.println("c == d :"+(c == d));
System.out.println("a.equals(b):"+a.equals(b));
System.out.println("c.equals(d):"+c.equals(d));
}
運行結果:
a == b :true
c == d :false
a.equals(b):true
c.equals(d):true
e.equals(a):true
對於 a == b :true,因爲Java中內存分成兩種:一種是棧stack,一種是堆heap。函數中的一些基本類型的變量(int, float)和對象的引用變量(reference)都在函數的棧中,(工作於編譯階段, 生成class文件之前)分配。存取速度快,稍遜於寄存器, 比堆快,函數執行完後,Java會自動釋放掉爲函數裏變量開闢的棧內存空間,該內存空間可以立即被另作他用。堆heap內存用來存放由new創建的對象和數組。堆內存,負責運行時(runtime, 執行生成的class文件時)數據,由JVM的自動管理。缺點是,存取速度較慢。 棧中的引用變量指向堆中的對象或數組。
而棧中有共享池的概念,比如上面例子中,a=”abc”;在棧中創建一個String對象引用變量a,然後看看棧中有沒有”abc”,如果沒有,則將”abc”存放進棧,並令a指向”hello”,如果已經有”abc” 則直接令a指向“abc”。對於int, float 類型的變量也是一樣的有這種共享池的概念,注意上述的工作是在compile(編譯)的階段完成的,而不是runtime運行時完成的。所以a和b指向的是同一個對象。地址當然相同,所以a == b爲true,a.equals(b):true。
但是String c = new String(“123”);String d = new String(“123”);是用new()來新建對象的,存於堆中,沒調用一次就會創建一個新的對象。所以c和d是兩個完全不同的對象,但是表示的字符序列是相同的,所以c == d :false,c.equals(d):true。