2011-05-04 85 views
0

大多數時候我在需要使用它們的相同類中定義常量。創建用於定義常量的類

但現在我必須在一個單獨的類中定義所有常見的常量。我見過定義類的兩個常量常量版本:

a。如果您嘗試創建Consts的對象,將會導致編譯時錯誤。

final class Consts { 
     private Consts(){} 

     public static final String TAG = "something"; 
    } 

b。如果您嘗試創建Consts的對象,則會拋出運行時異常。

final class Consts { 
     public Consts(){ 
      throw new RuntimeException(); 
     } 

     public static final String TAG = "something"; 
    } 

檢查這個類的機器人http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/Manifest.java 爲什麼他們使用了第二個版本?

我應該使用哪一個,爲什麼要去第二個版本?

+1

您還可以創建一個'enum'。 – romaintaz 2011-05-04 06:42:05

回答

1

從我的角度來看,沒有理由使用第二種方法。這是API的誤導,因爲該類暴露了一個可見的構造函數,在任何情況下都會拋出異常。客戶可能陷入這個陷阱。

然而,還有其他的選擇,例如,你可以把Consts接口

interface Consts { 
    String TAG = "somthing" 
} 

這將允許實現該接口,從而具有「更容易」訪問常量(不使用靜態進口)類。另一個好處是,即使您的IDE中只有已編譯的類,也可以使用查找引用。由於編譯器會將常量內聯到使用類中,因此很難找到對TAG的引用。如果客戶端實現該接口,他們可以很容易地查找。但是,一些編碼指導禁止這樣做。

可能的下一個選項是枚舉。 JVM將確保enum類中每個常量只有一個實例:

enum Consts { 
    TAG, OTHER, .. 
} 
3

我沒有看到第二個版本的任何理由,因爲第一個版本(private構造函數)完全按照您的要求進行。

另一個常見的問題是讓常量持有者interface。然而,這並不是普遍認可的,並且可能導致人們接口,這通常被認爲是代碼味道。

+0

檢查這個類的http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/Manifest.java 他們得到什麼好處通過在構造函數中拋出異常。 – Vivart 2011-05-04 06:44:58

+1

由於某些原因,事情並不總是以某種方式產生,有時候這只是習慣。防止這些類的實例化非常重要,以至於任何人都無法做到他們想要的。 PS:我不喜歡界面技巧,我覺得它過度殺傷 – gd1 2011-05-04 06:49:04

+1

我不認爲android的例子是一個很好的例子。構造者混淆了客戶(和代碼的讀者)。他們應該是私人的(並且仍然可以拋出異常)。 – 2011-05-04 06:49:59

1

你可以使用兩者,首先是更簡單和更好,因爲會導致'編譯'錯誤,而不是運行時,即你之前發現問題。

您也可以在包中使類不是私有的(不使用public修飾符),並將其他類寫入包(如果它總是寫入它們),以便它們不會實例化該類。是的,Java是面向對象的,但你並不需要迂腐。 :)我從來沒有見過任何人錯誤地實例化一類靜態字段,如果他/她這樣做,則不會造成任何傷害。