[英]static and final in java
我正在從這個頁面閱讀Java中的枚舉示例。
在第一個例子中,我唯一不理解的部分是在這部分代碼中使用static
關鍵字:
private static final List<Card> protoDeck = new ArrayList<Card>();
// Initialize prototype deck
static {
for (Suit suit : Suit.values())
for (Rank rank : Rank.values())
protoDeck.add(new Card(rank, suit));
}
public static ArrayList<Card> newDeck() {
return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
}
為什么protoDeck聲明為static
和final
? 然后,使用靜態循環初始化protoDeck。 我知道靜態變量,它們在對象實例之間保留它們的值。 但這是一個單例類(私有構造函數),因此無法實例化。
那么這樣做有什么好處呢? 如果proteDeck不是static
和final
會有什么影響?
從技術上講,這不是一個單身人士類。 (單身有一個實例,這個沒有 !)
它是ArrayList<Card>
的工廠方法 , newDeck
方法的工作方式與構造函數對“CardArrayList”類的工作方式相同。 它不是Java構造函數,而是工廠方法,但除此之外它起到同樣的作用:創建新的卡片組。
使用類CardArrayList
和子類型ArrayList
顯然是一種替代方案。 試試這個練習:寫一下類,這樣就可以達到同樣的目的。 嘗試使用常量( static final
)來保持初始對象集。 您會注意到這兩者之間幾乎沒有什么區別,除了這種方法明確表示沒有添加功能,但結果是“除了包含完整ArrayList<Card>
的ArrayList<Card>
”。 子類化可能意味着有額外的功能,例如確保甲板不被混淆。
static final
變量包含用作新對象模板的原型。
代碼的靜態{....}部分將在Java虛擬機加載類的位置執行。
在您的代碼段中,它用於初始化protoDeck ArrayList。
這不遵循Singleton模式,因為您的代碼中沒有證據表明該類只實例化了一次。
在類初始化( static
括號中的代碼)中,程序生protoDeck
牌的所有卡並將其存儲在protoDeck
。
調用newDeck
,將返回deck的淺表副本。 這意味着游戲中的所有牌對象都是同一個對象(只有一張“黑桃王牌”牌)。 不過,他們在幾個不同的套牌中進行管理。
恕我直言,這是一個有點太復雜了這個例子中,它會更有意義,如果不是Cards
,而其他種類的類(即一個在那里他們代表的系統資源-database連接的初始化將是昂貴的/在RAM昂貴,或其他或類似 - )。
如果它不是靜態的,代碼將無法編譯,因為newDeck方法是靜態的,而newDeck是靜態的,因為你沒有為不同的卡獲得不同的套牌。
讓它不是最終的不會做任何不同的事情。 這是最終的,因為你不能分配不同的數組。 但你仍然可以添加它,所以它不是一成不變的。 所以這是一個常見的線索,但不是行為的改變。
Java中的final
關鍵字可以實現各種編譯時魔術。 例如,當編譯器知道永遠不會重新分配變量時,它可以執行“ memoization ”優化。
僅此一項是默認情況下final
確定局部變量,參數和類成員的一個很好的理由 - 當然,除非你真的必須能夠重新分配它們。
如果protoDeck
不是static
,那么每張Card
都會有一個,這不是一件好事。
顯然,您只能使用static
代碼構造static
變量。
final
只是意味着protoDeck
永遠不會被替換(雖然它可以在內部更改)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.