2009-09-03 39 views
26

如果我想要集中聲明靜態常量的集合,以便它們可以在各種項目之間共享,並將它們放入類或接口(Java)中。應該將常量集合放在類或接口中嗎?

在過去,我已經看到他們大多放在一個類,但我開始認爲,因爲類不會,也不應該實例化,也許他們會在界面更好,但接口不應該實現任何類,例如

public class ErrorCodes { 
    public static final String ERROR_1 = "-1"; 
    public static final String ERROR_2 = "-2"; 
} 

public interface ErrorCodes { 
    public static final String ERROR_1 = "-1"; 
    public static final String ERROR_2 = "-2"; 
} 

回答

27

如果他們有很強的聯繫,然後我把它們放在一個枚舉:

public enum Error { 
    ERROR_1("-1", "foo went wrong"), 
    ERROR_2("-2", "bar went wrong"); 

    private final String id; 
    private final String message; 

    Error(String id, String message) { 
    this.id=id; 
    this.message=message; 
    } 

    public String getId() { 
    return id; 
    } 

    public String getMessage() { 
    return message; 
    } 
} 

的好處是,你可以有類型安全的代碼並且您可以輕鬆地添加基於id的查找(通過在構造函數中構建HashMap<String,Error>或僅通過循環遍歷values())。

+0

枚舉實際上是一個更好的方法。我想我沒有仔細閱讀他的問題,以便理解他的意圖。 – 2009-09-03 12:08:27

+1

我發現這是最好的解決方案,因爲您可以將數字和字符串保存在一起,並從屬性文件加載字符串。一切都在一個地方。 – 2009-09-03 12:10:46

+0

如果你有大量的常量,或者它在某個點之後是否會影響性能,這仍然是最好的方法嗎? – Yonetmen 2018-03-08 09:30:02

4

你應該在班上做。

接口是類用戶可以訪問的可用方法,屬性等的描述 - 通過實現接口,可以保證在接口中聲明的成員對用戶可用。

另一方面,類是對一個對象的描述,或者(如果你不是,那麼對OO原則很難......)靜態成員的佔位符。我個人認爲它在一些項目中非常有用,可以將一堆常量存儲在Settings類中,所以我不必在整個項目中查看定義。我認爲這種方法也是你追求的。

+0

在類中收集常量,併爲其提供一個私有構造函數以防止它被實例化。 – 2016-07-03 13:47:25

5

使用static import應該在這裏考慮(用於導入在類中定義的常量)或type-safe Enum

Interface for constants

配售常量的接口是用Java的早期流行的技術,但現在許多人認爲它討厭使用的接口,因爲接口應該處理由提供的服務對象,而不是它的數據
同樣,一個類使用的常量通常是一個實現細節,但將它們放在一個接口中會將它們提升到該類的公共API。

2

你應該把它們放在帶有私有構造函數的類上。

public class ErrorCodes { 
    private ErrorCodes() {} // prevents instantiation 
    public static final String ERROR_1 = "-1"; 
    public static final String ERROR_2 = "-2"; 

}

或者更好的是,使用類型安全枚舉。

5

這已經討論before

爲什麼你不希望在一個界面中的常數的原因是,它誘使客戶端類爲「實行」該接口(爲了訪問常量無前綴他們與接口名稱)。但是,您不應該 - 界面實際上不是對象的功能的接口,而是在類的外部類型中編譯時的便利。

曾幾何時,「恆界面」是很方便的一段時間,但它一直是「錯誤的」,甚至不是懶惰的藉口,現在使用它,我們有import static語句。

編輯:雖然我必須同意針對您的問題中提出的場景,枚舉更合適。

0

我個人認爲常量應該在類中定義,原因與上面所述的相同。特別是因爲一些開發人員通過在想要使用它們的類中實現接口來使用這些常量。當那個接口包含很多常量時,你不再需要查看該特定類的javadoc,因爲它常常被該類的常量描述所忽略。

2

我推薦靜態導入和常量接口的組合。

如果Java接口具有恆定的字段聲明,請記住,這些都是隱含公共,靜態和最終(見Java語言規範,Section 9.3。)因此,你總是可以省略這些修飾,只留下類型,和你的不斷接口應該是這樣的:

public interface Constants { 
    int AGE = 0x23; 
    String NAME = "Andrew"; 
    boolean IGNORE = true; 
} 

這應該,當然,永遠如下被使用:

import static Constants.*; 

public Whatever { 
    public String method() { 
     return String.format("%s is %d%c", NAME, AGE, IGNORE ? '?' : '!'); 
    } 
} 

在我的生產代碼中,我沒有使用這種風格的問題,並且感覺它會導致一個非常整潔,緊湊的常量集合,並且可以處理各種類型的常量,這是枚舉所不能的,並且能夠被擴展如果需要,不像枚舉。

另一種不是每個人都會贊同的可能性是在父接口中嵌套接口(甚至枚舉類型),允許您將常量分組。這:

interface MoreConstants { 
    int MAGIC = 0xCAFEBABE; 
    interface PROPERTIES { 
     String NAME = "name"; 
    } 
    enum ERRORS { 
     ON_FIRE, ASLEEP, BROKEN, UNSURE; 
    } 
} 

和訪問他們喜歡這個,假設MoreConstants的靜態導入接口:

if (!PROPERTIES.NAME.equals(value)) { 
    return ERRORS.UNSURE; 
} 

當然,這些接口不應該被實現,我會考慮的做法不好。但確保這一點的唯一方法是嚴格的代碼審查...

+0

你不會碰到的一個問題是,一些常量會在編譯時被複制到生成的字節碼中,而不是被引用,留給你一個ABI,你不能在不破壞東西的情況下改變它。 – 2009-09-18 18:35:52

+0

由於直接字段訪問,這對於'常量類'解決方案不是問題嗎? – grkvlt 2009-09-18 20:00:38

+0

是的,我認爲同樣的事情發生在類和接口,但我可能是錯的。 +1給enum的答案 – 2009-09-19 02:47:15

相關問題