標籤:throw static 系統 class 目的 建構函式 構造器 char detail
通過反射還是可以修改的。public static void stringReflection() throws Exception { String s = "Hello World"; System.out.println("s = " + s); //Hello World //擷取String類中的value欄位 Field valueField = String.class.getDeclaredField("value"); //改變value屬性的存取權限 valueField.setAccessible(true); char[] value = (char[]) valueField.get(s); //改變value所引用的數組中的第5個字元 value[5] = ‘_‘; System.out.println("s = " + s); //Hello_World} ===為什麼string是不可變對象,有什麼優勢?底層使用private final char value[];有一個private final的數組 1.節省堆空間,string對象建立後會存入字串常量池中,同一個string可以有不同的指標同時指向。保證唯一性,多執行緒同一個string的時候不用擔心線程問題,因為不可變。 2.安全性考慮。---資料庫帳號密碼---網路編程的連接埠號碼和ip---類載入器載入類的時候都是通過string來傳遞,如果可變會造成系統漏洞 3.用於當hashmap的鍵特別適合,因為hashcode不變不需要重複計算,直接緩衝這個hashcode ===如何建立一個不可變類?簡述:成員變數是private final類型,初始化用建構函式複製的方式初始化,沒有set方法,get方法使用複製的方式進行訪問。---類定義:final修飾類,不能夠繼承---成員變數:1.成員變數設為私人private final,通過構造器初始化;2.不為成員變數設定set方法;3.如果有可變對象那麼初始化的時候必須使用clone的方式進行初始化,建立一個對象初始化,否則會影響到原有的對象。---方法:1.對於不可變對象中的可變對象的訪問方式:比如說有個map,那麼如何擷取呢?get方法不能夠直接返回對象本身,而是通過複製來返回對象,這樣修改未經處理資料不會影響建立的這個資料。2.同時構造器進行初始化對象的時候必須建立一個新的hashmap來複製建構函式的入參map,就是複製目的:比如我有三個屬性int,string,hashmap用來初始化了一個不可變對象,那麼我擷取到對象中的hashmap的引用,擷取引用使用hasmap.clone()方法,那麼這個引用指向新的數組地址,但是如果hashmap內部有對象引用的話,是不會進行複製的,還是指向了原有的對象。 ===hashmap的clone方法是深拷貝還是淺拷貝呢?K key = e.getKey();V value = e.getValue();putVal(hash(key), key, value, false, evict);這個是entry複製的內部實現,索引值對都會進行建立。如果是參考型別的時候,只是複製了引用,所以修改新的或者舊的引用的時候都是指向同一個堆空間中的對象的。http://blog.csdn.net/wangbiao007/article/details/526250991.HashMap的clone方法產生新的對象,新的對象有自己獨立的儲存空間。2.雖然HashMap的clone方法產生了新的對象,但新的HashMap和原來的HashMap所儲存的參考型別都是指向的同一儲存空間。這就導致在對HashMap中的元素進行修改的時候,即對數組中元素進行修改,會導致原對象和clone對象都發生改變,但進行新增或刪除就不會影響對方,因為這相當於是對數組做出的改變,clone對象新產生了一個數組。
java基礎---不可變對象建立