Java 憑藉面向對象、跨平台、可移植性強、安全性高等優勢,已成為企業級應用開發的首選語言。在跨平台環境下運行 Java 應用時,往往需要動態獲取作業系統類型、JDK 版本、用戶工作目錄等隨環境變化的資訊,以確保程式正確執行。JDK 提供的 java.util.Properties 類(系統屬性類)讓這項工作變得輕而易舉。此外,開發者還可自訂屬性檔,於執行期動態載入以控制程式行為。本文將深入解析 Properties 類的核心方法、常見系統屬性鍵值、自訂屬性檔操作實戰,以及安全策略檔的定義與應用。
contains(Object value) / containsKey(Object key):判斷值或鍵是否存在,返回布林值。getProperty(String key) / getProperty(String key, String defaultValue):根據鍵獲取值,支援預設值。list(PrintStream out) / list(PrintWriter out):將屬性表輸出至指定流。size():返回屬性鍵值對數量。put(Object key, Object value):新增或更新鍵值對。remove(Object key):移除指定鍵。| 屬性鍵 | 說明 | 典型值範例 |
|---|---|---|
file.separator | 檔案分隔符 | Windows: \;Unix/Linux: / |
user.home | 用戶主目錄 | C:\Users\Admin / /home/user |
java.home | JRE 安裝目錄 | C:\Program Files\Java\jre1.8.0_301 |
java.ext.dirs | 擴展類庫目錄 | C:\Program Files\Java\jre1.8.0_301\lib\ext |
os.name | 作業系統名稱 | Windows 10 / Linux |
user.name | 用戶登入名稱 | admin |
os.version | 作業系統版本 | 10.0 |
path.separator | 路徑分隔符 | Windows: ;;Unix: : |
user.dir | 當前工作目錄 | D:\JavaProject |
import java.util.Properties;
public class GetSystemProperties {
public static void main(String[] args) {
// 取得系統屬性並建立 Properties 物件
Properties props = new Properties(System.getProperties());
// 輸出至標準輸出
props.list(System.out);
// 實務上可根據屬性決定執行邏輯,例如:
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
// Windows 專屬邏輯
} else if (os.contains("nix") || os.contains("nux")) {
// Linux/Unix 專屬邏輯
}
}
}
執行後將在主控台列印完整屬性清單,開發者可據此撰寫跨平台相容邏輯。
屬性檔(.properties)是外部化配置的經典方式,適合存放不需重新編譯即可修改的參數(如功能開關、版本號、路徑等)。
import java.io.*;
import java.util.Properties;
public class PropertyFileDemo {
public static void main(String[] args) {
Properties props = new Properties();
FileInputStream fis = null;
FileOutputStream fos = null;
try {
// 1. 載入既有屬性檔
fis = new FileInputStream("config.properties");
props.load(fis);
// 2. 動態修改屬性(例如啟用某功能)
props.setProperty("feature.enabled", "true");
props.setProperty("last.modified", String.valueOf(System.currentTimeMillis()));
// 3. 寫回新檔案(附加註釋)
fos = new FileOutputStream("config_updated.properties");
props.store(fos, "Updated by PropertyFileDemo at " + new java.util.Date());
System.out.println("屬性檔更新完成!");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 關閉流
try { if (fis != null) fis.close(); } catch (IOException ignored) {}
try { if (fos != null) fos.close(); } catch (IOException ignored) {}
}
}
}
config.properties# 應用配置
feature.enabled=false
version=1.0.0
data.dir=./data
config_updated.properties# Updated by PropertyFileDemo at Mon Jan 15 10:30:45 CST 2024
feature.enabled=true
version=1.0.0
data.dir=./data
last.modified=1705285845123
透過此機制,運維人員無需修改程式碼即可調整應用行為,極大降低維護成本。
Java 安全架構基於 java.security.Policy 實現程式碼級權限控制。策略檔分三級載入,優序遞增:
${java.home}/lib/security/java.policy)${user.home}/.java.policy)-Djava.security.policy=... 指定)grant {
// 允許讀取特定系統屬性
permission java.util.PropertyPermission "user.dir", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "java.class.path", "read";
permission java.util.PropertyPermission "user.name", "read";
// 允許網路連接(範例)
// permission java.net.SocketPermission "example.com:80", "connect,resolve";
// 允許檔案讀寫(範例)
// permission java.io.FilePermission "/tmp/-", "read,write,delete";
};
關鍵點:
grant 區塊定義授予的權限集合;可加上 codeBase 或 signedBy 限定適用程式碼來源。PropertyPermission 的第二參數為動作:read / write。System.getProperty("file.separator") 等。.properties 或 YAML 檔,啟動時載入。config.properties.template)納入版控,正式環境由部署流程產生實際檔案。WatchService 監聽檔案變更),實現熱更新。掌握系統屬性與自訂屬性檔的操作,是打造靈活、可維護、跨平台 Java 應用的關鍵基石。