天天看點

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

1.基本資料類型與對象資料類型

基本資料類型(primitive types):

int、 long、boolean、 double、 char……

對象資料類型(object types):

Integer、Long、Boolean、Double、String、StringBuilder……

在Java約定中,基本資料類型是以小寫字母開頭,而對象類型以大寫字母開頭。

下圖很好的說明了二者的差別:

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

boxed primitives:将基本類型包裝為對象類型,例如Boolean, Integer, Short, Long, Character, Float, Double。通常是在定義集合類型的時候使用它們。一般情況下,盡量避免使用。一般可以自動轉換。

2.靜态類型檢查與動态類型檢查

靜态類型檢查 static checking:在程式運作之前檢查發現bug。在編譯階段發現錯誤,避免了将錯誤帶入運作階段,可提高程式的正确性與健壯性。其主要檢查目标包括:

  • 文法錯誤(Syntax errors)
  • 類名/方法名錯誤(Wrong names)
  • 參數數目錯誤(Wrong number of arguments)
  • 參數類型錯誤(Wrong argument types)
  • 傳回值類型錯誤 (Wrong return types)

動态類型檢查 Dynamic checking:在程式運作中檢查發現bug。其主要檢查目标包括:

  • 非法的參數值 (Illegal argument values)
  • 非法的傳回值 (Unrepresentable return values)
  • 越界 (Out-of-range indexes)
  • 空指針 (Calling a method on a null object reference)

此外還有一種無檢查:這種不會幫助使用者查找bug,需要親自檢查錯誤。

顯然靜态類型檢查要優于動态類型檢查要優于無檢查。

靜态檢查與動态檢查對比:靜态檢查是關于“類型的檢查”,不考慮值,而動态檢查是關于“值”的檢查。

3.值的改變與引用

首先先來讨論一個問題,改變一個變量與改變一個變量的值有何差別?

  • 改變一個變量:将該變量指向另一個值的存儲空間
  • 改變一個變量的值:将該變量指向的存儲空間寫入一個新的值

4.Mutability與Immutability

Immutability不變性:

對于immutable類型的變量,一旦被建立出來其值不能被改變。如果是引用類型,一旦确定其指向的對象也不能在改變。

對于這種變量可以用final關鍵詞修飾,注意如果編譯器無法确定final變量不會改變,就會提示錯誤,這是靜态檢查的一部分。實際程式設計中應盡量使用final變量作為方法的輸入參數、作為局部變量。其代表了程式員的一種設計決策。

注意:

  • final類無法派生子類
  • final變量無法改變值與引用
  • final方法無法被子類重寫

需要注意的是:String類型是immutable類型,而StringBuilder才是mutable類型

二者快照圖(snapshot diagram)對比:

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)
第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

此時看沒有差別,但當引用變多時就會出現不一樣的結果,例如:

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

另外使用immutable類型時如果頻繁修改會産生大量的臨時拷貝,GC(垃圾回收,第八章會詳細說明)負擔就重了。此時最好用mutable類型。

關于immutable與mutable資料類型差別:immutable類型更安全,而mutable類型則在其他品質名額上表現更好,實際使用選擇應該具體情況。

5.防禦式拷貝

當類中的一個方法傳回了一個可變的成員變量時,而且不希望其被使用者修改時,可以采用防禦式拷貝的政策進行程式設計。

方法較為簡單,現隻給出一個簡單的示例:

存在風險代碼:

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

這裡說明一下,因為傳回的是Date資料類型為mutable類型,是以如果用戶端得到這個類型變量并修改了它,會導緻period類内部資料修改,這是一個很嚴重的表示洩漏(後面會詳細說明)。mutable類與immutable類如果是有C/C++基礎的會感覺很奇怪,稍微唠叨一下。mutable類進行傳參的時候類似于C/C++指針傳參,對其進行修改會對源資料進行修改。java并沒有指針這項内容,取而代之的就是mutable與immutable。

進行防禦式拷貝後:

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

6.快照圖(Snapshot diagram)

Snapshot 是一個code-level, run-time, and moment view。用于描述程式運作時的内部狀态 ,好處是用于描述程式運作時的内部狀态 ,便于刻畫各類變量随時間變化 ,便于解釋設計思路

具體使用方法:

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

若對象是不可變對象用雙線橢圓:

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

當值改變時:

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

不可變引用:用雙線箭頭。

第三章 ADT與OOP——資料類型基礎1.基本資料類型與對象資料類型2.靜态類型檢查與動态類型檢查3.值的改變與引用4.Mutability與Immutability5.防禦式拷貝6.快照圖(Snapshot diagram)

注意:此時引用是不可變的,但是指向的值是可變的,可變的引用,也可指向不可變的值。

繼續閱讀