2009-01-28 75 views
9

我們的代碼使用了很多系統屬性,例如'java.io.tmpdir','user.home','user.name'等。我們沒有爲這些定義任何常量任何地方(也不是我認爲的Java)或任何其他聰明的東西來處理它們,因此它們在整個代碼中散佈在純文本中。使用Java系統屬性的最佳實踐

String tempFolderPath = System.getProperty("java.io.tmpdir"); 

大家如何使用系統屬性?

回答

8

我會把它當作其他字符串常量分散在整個代碼中,併爲它定義一個常量變量。當然,在這種情況下,「java.io.tmpdir」不太可能改變,但你永遠不知道。 (我並不是說Sun可能會改變「java.io.tmpdir」的含義,或者它指向什麼系統屬性,但是您可能會改變主意瞭解您需要閱讀的系統屬性。)

如果你只在一個類中使用一個特定的屬性,那麼我會在該類中定義常量。

private final String TEMPDIR = "java.io.tmpdir"; 

如果你使用不同類相同的屬性,您可能希望定義一個靜態類自己的抱着你最常使用的常量。

public final Class Prop { 
    public static final String TEMPDIR = "java.io.tmpdir"; 
    ... 
} 

然後,無處不在,你需要使用常量只是把它用

System.getProperty(Prop.TEMPDIR); 
+0

但是你會怎麼做?爲某些系統屬性創建某種常量只是接口的某個地方?從來沒有真正的他們的粉絲。有什麼建議麼? – willcodejavaforfood 2009-01-28 13:28:19

+0

我添加了幾個不同的建議,但我認爲對於不同類別的常量字符串,您所描述的界面是最好的方法。 – 2009-01-28 13:37:55

+0

夠公平的。 Daft問題真的:) – willcodejavaforfood 2009-01-28 13:49:55

1

我把這些作爲任何其他不變,可能有P_PROP_前綴,並把它們放在一個適當的常量類。

如果你使用他們很多,我甚至考慮拆分出來的PropertyNames常量類:

public final class PropertyNames 
{ 
    private PropertyNames() 
    { 
    // no instantiation 
    } 

    public static final String P_VAR_DIRECTORY = "org.acme.app.varDir"; 

    public static final String P_TMP_DIRECTORY = "java.io.tmpDir"; 
} 

最後,我會認真考慮的命名空間屬性名稱本身,與標準的反向域名用於包裝。這只是爲了避免與第三方財產消費者發生衝突。

4

如果你在多個地方使用它,寫一個類來封裝讀取屬性和其他屬性可能是一個好主意。

所以也許是這樣的:Configuration.getTemporaryDirectory()

3

由於問題的標題極爲廣泛,我會扔在使用系統屬性時,你應該考慮的另一個很好的做法。訪問系統屬性可以由SecurityManager拒絕,所以你可能需要通過PrivilegedAction,像這樣訪問他們:

String tmpdir = AccessController.doPrivileged(new PrivilegedAction<String>() { 
    public String run() { 
    return System.getProperty("java.io.tmpdir"); 
    } 
}); 

當你的代碼限制一個動作靈敏,使其即使是安全的使用特權操作惡意代碼會調用它。

例如,在像OutputStream open(File file)這樣的方法中使用特權操作是不安全的。不受信任的代碼可以調用它,並使用你的代碼的特權在任何地方寫任何東西。

但是,如果您有一種將您的應用程序的用戶首選項保存到您選擇的文件的方法,那可能是安全的。惡意呼叫者不能選擇文件位置或其內容;這些由您的代碼指定。所以,你的方法可以使用特權操作來允許它被非特權代碼調用。

4

我認爲在一個面向對象的軟件中,可能有一個對象(或方法)依賴於需要完成工作的目錄。所以,你可以證明這個依賴於構造函數或方法。 後,如果您需要爲目錄和默認來自系統屬性的默認,你可以簡單地創建一個工廠方法或構造函數/方法用更少的參數傳遞給其他costrunctor /方法:

new File(System.getProperty("java.io.tmpdir"); 

你不需要創建一個「依賴磁鐵」只包含一個配置參數。

0

在Java中,字符串是不可變的,這意味着內存空間中的同一對象不會被覆蓋;每次創建一個新的字符串。當前最高投票的建議是使用一個常數:

System.getProperty(Prop.TEMPDIR); 

不幸的是,所使用的常量是實際的屬性鍵。這意味着每次您進行此調用時,都將創建一個新的String對象來保存該值。在我看來,你應該不斷的調用本身的結果:

public static final String SYS_PROP_TEMP_DIR = System.getProperty("java.io.tmpdir"); 
4

SystemUtils被Apache Commons Lang中包提供,解決了這個問題。

SystemUtils定義常數對於大多數的系統屬性,其可以通過查找來獲得,例如:

import org.apache.commons.lang3.SystemUtils; 

class Something 
{ 
    public static void main(String[] args){  
     System.out.println(SystemUtils.JAVA_IO_TMPDIR); 
    } 
} 

可能,這是一個更清潔的方式來做到這一點。