- String類是不可變的,看下源碼(JDK 1.7)對類的描述
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
- 不能改變狀態的意思是,不能改變對象內的成員變量,包括基本數據類型的值不能改變,引用類型的變量不能指向其他的對象,引用類型指向的對象的狀態也不能改變。String類的外部無法修改String。也就是說一旦初始化就不能修改, 並且在String類的外部不能訪問這三個成員
- 對不可變類的代碼補充解釋
// 創建一個String 對象dstring,讓他的值爲hello
String dString = "hello";
/**
* 讓dstring 的值變爲world
* 這裏string 只是一個引用,指向了一個具體的對象,當dString = "world"; 這句話執行之後,
* 又創建了一個新對象“world” 原來的“hello”還存在內存中,並沒與改變
*/
dString = "world";
- 成員變量的String 聲明之後 默認值爲null
private static String a;
public static void main(String[] args) {
/**
* 成員變量 自動賦值null
*/
System.out.println(a);
/**
* bstring 是申明一個字符串 給他賦值爲空
* ctring 是申請一個字符串,沒有給他賦值,而是空引用
* 所以第二個會輸出出現NPE問題
*/
String bString = "";
String cString = null;
System.out.println(bString.trim());
System.out.println(cString.trim()); //會有NPE問題
/**
* 判斷字符串爲空
*/
if("" == bString || null == bString) {
//do somthing
}
String s0= "hello"; //聲明的變量存在棧內存中,會留存在字符串常量中緩存
String s1=new String("hello"); //定義的對象直接存在堆內存中,不會進入字符串常量,兩個值也不相等
String s2=new String("hello");
System.out.println( s0==s1 ); //flase
直接使用雙引號聲明出來的String對象會直接存儲在常量池中
如果不是使用雙引號聲明的String對象,可以使用string的intern方法
intern方法會從字符串常量池中查詢當前字符串是否存在,若不存在就會把當前字符串放入到常量池中
String s0= "hello"; //聲明的變量存在棧內存中,會留存在字符串常量中緩存
String s1=new String("hello"); //定義的對象直接存在堆內存中,不會進入字符串常量,兩個值也不相等
String s2=new String("hello");
s1.intern();
s2=s2.intern();
System.out.println( s0==s1.intern() );//true
System.out.println( s0==s2 ); //true