讀源碼String類

  • 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);
  • String 的"" 和 null 的問題
/**
		 * 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的內存地址相關
		String s0= "hello"; //聲明的變量存在棧內存中,會留存在字符串常量中緩存
		String s1=new String("hello"); //定義的對象直接存在堆內存中,不會進入字符串常量,兩個值也不相等
		String s2=new String("hello"); 
		System.out.println( s0==s1 ); //flase
  • intern方法
      直接使用雙引號聲明出來的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
		 








發佈了40 篇原創文章 · 獲贊 29 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章