2012-09-13 31 views
4

我正在設計一個純文本視頻遊戲,兩個角色並不常見在一起,但在心臟和性格上非常相似。如何使用內部靜態final字段初始化Java枚舉?

我的問題是,我不知道如何通過使用靜態最終內部常量的構造函數初始化一個enum常量。否則,這場比賽很好。 ;)

這裏的兩難境地:

  1. 枚舉常量必須在枚舉的第一行中定義,如果我沒有記錯
  2. 第一行不能引用後,任何未來(即「在定義之前不能引用字段」)

如何解決這個catch-22問題?

這裏下的非公開協議從遊戲中發佈了一些示例代碼:

enum ValiantHeroWithPrincessSavingTendencies { 

    SUPERMARIO(TYPICAL_QUOTE_FROM_MARIO), ZELDA(TYPICAL_QUOTE_FROM_ZELDA); 

    private String aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive; 

    public String getQuoteUnderStressfulCircumstances() { 
    return aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive; 
    } 

    private ValiantHeroWithPrincessSavingTendencies(String quote) { 
    aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive = quote; 
    } 

    private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!"; 
    private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!"; 
} 

我試圖用SUPERMARIO TYPICAL_QUOTE_FROM_MARIO,但我還沒有定義TYPICAL_QUOTE_FROM_MARIO尚未初始化。我想,在SUPERMARIO之前移動私有靜態最終字段是非法的。

+3

我說simplier,只是反過來這樣做。但是你把這些領域變成了「私人」。他們怎麼會有用?這一切背後的功能需求/設計考慮是什麼? – BalusC

+2

爲什麼不把字符串放在枚舉構造函數中,而不是有一個無用的(私有)靜態final字段呢?像這樣:'SUPERMARIO(「有在你!」),...' – aymeric

+0

@BalusC ...但它是_Object-oriented_ :-) –

回答

8

唯一可行的選擇是a)將你的常量移動到另一個類,或b)把你的常量直接放入值初始值設定項中。

如果您移動常數,可以使類的靜態類在枚舉:

enum ValiantHeroWithPrincessSavingTendencies { 
    SUPERMARIO(Quotes.TYPICAL_QUOTE_FROM_MARIO), 
    ZELDA(Quotes.TYPICAL_QUOTE_FROM_ZELDA); 

    private String aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive; 

    public String getQuoteUnderStressfulCircumstances() { 
    return aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive; 
    } 

    private ValiantHeroWithPrincessSavingTendencies(String quote) { 
    aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive = quote; 
    } 

    private static class Quotes { 
    private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!"; 
    private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!"; 
    } 
} 
+0

我喜歡這個!讓我們看看是否有人可以做得更好,但我已經在我的VideoGameEditor中輸入了這個...讓我們看看我是否可以通過保存一些公主來獲得幾個小時的樂趣.. – Robottinosino

+0

爲什麼要爲那些僅僅侷限於枚舉的東西而煩惱?沒有很好的理由,這太複雜了。 –

+1

@JimGarrison你可能想重複使用字符串。 「有在!「字符串也適用於某些尋找驅逐艦的驅逐艦;) – Brian

0

私人靜態最終常量是本地的枚舉;只需將它們編碼到實例定義中即可。在此之後,可以從aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive變量內部訪問它們。

+0

非常務實。但是,假設我有一個1M行的項目,並希望對其執行靜態分析以檢測硬編碼文字(有點像「FindBugs」或某種「CheckStyle」)?突然之間,我必須打破只是因爲'enums'古怪的方式對待「第一線」?嗯... – Robottinosino

0

你總是可以做一些哈克這樣的:

public enum Derp 
{ 
    SOMETHING(), 
    SOMETHINGELSE(); 

    private String herp; 

    public static final String A = "derp", B = "derp2"; 

    public String getHerp() 
    { 
     return herp; 
    } 

    static 
    { 
     SOMETHING.herp = A; 
     SOMETHINGELSE.herp = B; 
    } 
} 
+1

哇...這是哈克。我不會想到那個......有趣! – Robottinosino

+0

這不行嗎?我測試了它,它工作正常。 – Wug

+0

如果一個人不想吃東西,你會停止餵它們。你不會把胃打開,把食物推到肚子裏。 那麼,爲什麼在地球上,你會這樣做一個枚舉? –

4

您可以通過類名剛剛訪問它們:

enum ValiantHeroWithPrincessSavingTendencies { 
    SUPERMARIO(ValiantHeroWithPrincessSavingTendencies.TYPICAL_QUOTE_FROM_MARIO), 
    ZELDA(ValiantHeroWithPrincessSavingTendencies.TYPICAL_QUOTE_FROM_ZELDA); 

    ... 

    private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!"; 
    private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!"; 
} 

它比Brian的解決方案

+0

哇,我很驚訝這個編譯器錯誤的作品。但是,這隻適用於編譯時內置的常量(基元和字符串);否則,在常量初始化之前初始化枚舉值時,將該常量解除引用。 –