2012-11-27 51 views
3

起初我只是想提出一個關於Image這個課的問題,但我想盡可能廣泛地應用它。動態加載可能異常的對象是否可以聲明爲final?

基本上,這是場景。我正在爲GUI常量創建一個文件,在這個文件中,我想爲每個我正在使用的Image都有最終變量。所以我的字段聲明如下UP_ARROW是:

public static final Image UP_ARROW; 

然後我嘗試加載它們當ImageIO API,就像這樣:

static { 
    UP_ARROW = ImageIO.read(new File("img/upArrow.png")); 
} 

不幸的是,這是無效的,編譯代碼,因爲它明確throws IOException,我必須處理。所以我修改它並用try/catch包圍它:

static { 
    try { 
     UP_ARROW = ImageIO.read(new File("img/upArrow.png")); 
    } 
    catch(IOException ioe) { 
     //TODO 
    } 
} 

現在我得到一個不同的編譯器錯誤。這次它說有可能該字段可能沒有被初始化。好的,這是有道理的。感謝您指出這一點,編譯器。這似乎是一個簡單的辦法:

static { 
    try { 
     UP_ARROW = ImageIO.read(new File("img/upArrow.png")); 
    } 
    catch(IOException ioe) { 
     UP_ARROW = null; 
    } 
} 

現在,無論什麼時候,在UP_ARROW必須以我的形象或null填充。我準備宣佈勝利並繼續前進。但現在我得到另一個,意外的編譯器錯誤:

The final field UP_ARROW may already have been assigned

...再次受挫,編譯器!

因此,問題:有沒有辦法解決這個問題,這樣我可以在運行時動態加載最終字段?或者我宣佈失敗,並簡單地使Image是非最終?

另外,爲什麼編譯器不允許這樣做的解釋也會有幫助。據我瞭解,根據上面的代碼,UP_ARROW對象不可能已經分配到達catch{}塊之前,,因爲這是必須拋出異常。所以如果try{}成功執行,只發生一次分配。如果它沒有成功執行,仍然只有一項任務發生。那是不是有效的?

回答

4

下應該這樣做:

static { 
    Image up_arrow = null; 
    try { 
     up_arrow = ImageIO.read(new File("img/upArrow.png")); 
    } 
    catch(IOException ioe) { 
     // log the error? 
    } 
    UP_ARROW = up_arrow; 
} 

這可能是有意義的圍在finally塊的最終分配。

1

NPE的回答是不錯的,但我認爲這是一個(基於脫下和)更好:

public enum Arrows { 
    UP ("img/upArrow.png"), 
    DOWN ("img/downArrow.png"), 
    LEFT ("img/leftArrow.png"), 
    RIGHT ("img/rightArrow.png"); 

    public final Image myImage; 

    private Arrows(String fileName) { 
     Image tempImage; 
     try { 
      tempImage = ImageIO.read(new File(fileName)); 
     } catch (IOException e) { 
      tempImage = null; 
     } 
     myImage = tempImage; 
    } 
} 

這解決您的問題,給你一個enum超過static final變量的所有優點。

相關問題