2012-08-02 45 views
12

這是有效的Java使用中的int枚舉模式是脆性說明int枚舉模式是編譯時常量是什麼意思?

程序。因爲int枚舉是 編譯時常量,所以它們被編譯到使用它們的客戶端中。

有誰能解釋爲什麼INT枚舉模式被稱爲編譯型常數,什麼是編譯到客戶是什麼意思?

這裏S'這樣的恆定的例子:

public static final int APPLE_FUJI = 0; 
+0

它是少數幾個優化'javac'中的一個,通常我寧願它沒有;) – 2012-08-02 08:15:04

回答

17

假設你有兩個文件:

Foo.java: 
public class Foo 
{ 
    public static final int SOMETHING = 1; 
} 

Bar.java: 
public class Bar 
{ 
    public static void main(String[] args) 
    { 
     System.out.println(Foo.SOMETHING); 
    } 
} 

編譯他們兩個,跑java Bar,它會打印出1

現在改變Foo.java使SOMETHING爲2,並重新編譯只是富.java。重新運行java Bar並且它將會仍然打印1.常量值將被複制到使用它的每段代碼,而不是在執行時詢問Foo的值。

在實踐中,如果您隨時隨地重新編譯所有內容,這不是問題。

+0

是不是Java的動態綁定語言?爲什麼我們必須重新編譯所有內容? – Geek 2012-08-02 08:15:17

+2

@Geek你不**有**做到這一點。但強烈建議您避免Jon Skeet在上面描述的內容。在我看來,Java編譯器的這種行爲是不好的。該常量應該只存儲在'Foo.class'中。 '酒吧'應該總是從'Foo'得到那個常數。像許多其他半愚蠢的東西一樣:它不會被改變,因爲它可能會破壞現有的代碼。一羣哭泣的嬰兒...... – 2012-08-02 08:19:24

+0

@Geek:你必須定義「動態綁定語言」才能回答你的第一個問題。但是在這種情況下你必須重新編譯的原因是因爲語言規範明確地調用了這樣的常量表達式。 – 2012-08-02 08:30:32

5

值‘0’本身將編譯期間被內置到.class文件。如果您然後更改該值,則必須重新編譯使用它的所有,包括使用您的應用程序/庫的任何客戶端代碼。

如果你不這樣做,你不會得到警告,而是不正確的行爲。

如果您的編譯時常量僅用於您的代碼中,那麼假設完整的清理/構建週期不會有問題。如果你的代碼能夠覆蓋更多的用戶,那麼這就成了一個問題。