【軟體構造】Mutable型別與Immutable型別
1.前言
在軟體構造這門課中,對mutable型別和immutable型別的深入理解,有助于后續ADT、可維護性、可復用性的學習,因此我們有必要對其進行詳細的分析說明,
我們首先明確的是,mutable型別和immutable型別均屬于ADT的范圍,二者關系如下圖:

2.概念
immutable類:類的實體創建后成員變數值不變,若修改后,參考會指向一個實體物件,
mutable類:類的實體創建后可以通過類的方法就地修改值,
3.常見immutable類與mutable類
常見immutable類:String類;基本資料型別與其封裝資料型別,如int、char、Interger、Boolean;Scanner類;經過 Collections.unmodifiableList/Map/Set() 方法處理后的集合,
常見mutable類:StringBuilder、StringBuffer、Map類、Collection類,
4.代碼實踐
考慮如下代碼:
String str=new String("123");
str.concat("4");
System.out.println(str);
輸出結果為:

為什么結果不是“1234”呢?
我們知道,java資料型別分為基本資料型別和物件資料型別(參考型別),后者型別的物件會按參考傳遞,這個參考,本質上是一個指標,指向存盤在堆里的物件物體,所以,對于這樣的變數,有著直接修改被指向的資料值和讓參考重新指向一個新物件兩種方式,
而對于immutable型別,一旦該類初始化為一個新物件,其指向的堆中的值不可以修改,除非讓其指向新的堆位置,所以,上述contact()會使用str參考指向的值重新創建一個新的物件,而不是修改str指向的物件的值,
其相應代碼快照圖為:

再考慮如下代碼:
StringBuffer strbuf1= new StringBuffer("123");
StringBuffer strbuf2=strbuf1;
strbuf1.append("4");
System.out.println(strbuf1);
System.out.println(strbuf2);
輸出為:

這里Stringbuffer為mutable型別,呼叫其成員方法append時,可以在參考所指向的堆中直接修改值,故輸出均為“1234”,
其代碼快照圖為:

對于mutable型別的物件,若有多個參考,其中某一個參考對物件的值修改時,由于所有參考指向同一個物件,所以在其他參考的值被“偷偷地改變了”,而這種改變,往往是被忽略的,因此會有潛在的危險性,
比如如下代碼:
strbuf2.append("5");
System.out.println(strbuf1);
在輸出strbuf2時,輸出結果也是“12345”,
此外在函式呼叫時,對于mutable類也會出現非法篡改的情況:
1 public static StringBuilder addstr(StringBuilder p){ 2 p.append("d"); 3 return p; 4 } 5 public static void main(String[] args) { 6 StringBuilder str=new StringBuilder("abc"); 7 System.out.println(str); 8 addstr(str); 9 System.out.println(str); 10 }
其輸出為:

5.針對immutable類非法篡改的解決方案
方案一:defensive copy
在傳參之前,或者在函式體內修改傳入引數之前,拷貝一個新的物件
1 public static StringBuilder addstr(StringBuilder p){ 2 StringBuilder copy=new StringBuilder(p); 3 copy.append("d"); 4 return copy; 5 } 6 public static void main(String[] args) { 7 StringBuilder str=new StringBuilder("abc"); 8 System.out.println(str); 9 StringBuilder str1=addstr(str); 10 System.out.println(str); 11 System.out.println(str1); 12 }
輸出為:
abc
abc
abcd
方案二:使用相應的immutable類替換mutable類的參考
1 public static String addstr(String p){ 2 return p+"de"; 3 } 4 public static void main(String[] args) { 5 String str=new String("abc"); 6 System.out.println(str); 7 String str1=addstr(str); 8 System.out.println(str); 9 System.out.println(str1); 10 }
輸出為:
abc
abc
abcde
6.總結
immutable類更加安全,在軟體構造程序中同時使用immutable型別的類,保證變數的值始終不變,可以重復使用,但對其修改需要進行大量拷貝,浪費時間與存盤空間;
mutable類的修改不會造成空間的浪費,適合作為共享資料使用,但對其修改一定要謹慎進行,
完結~感謝閱讀~??????
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/471775.html
標籤:其他
上一篇:批量上傳檔案或者上傳大檔案時 gateWay報錯DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
