首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 1.5+ 讀取環境變數完整指南:System.getenv() 實戰用法

     編輯:Java 相關知識

前言

Java 1.5 引入 System.getenv(),提供跨平台存取作業系統環境變數的標準 API。本文詳細說明單一變數讀取、全量遍歷、區域化編碼注意事項與容器化部署最佳實務。

基本 API


// 讀取單一環境變數(不存在回傳 null)
String os = System.getenv("OS");           // Windows_NT / Linux / Darwin
String javaHome = System.getenv("JAVA_HOME");
String path = System.getenv("PATH");

// 取得所有環境變數(不可修改的 Map)
Map<String, String> env = System.getenv();
// 注意:Map 為 unmodifiable,嘗試 put/remove 會拋 UnsupportedOperationException

完整範例:列印所有環境變數


import java.util.Map;

public class EnvDump {
    public static void main(String[] args) {
        Map<String, String> env = System.getenv();
        
        // 按鍵名排序輸出,方便閱讀
        env.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .forEach(entry -> System.out.println(entry.getKey() + "=" + entry.getValue()));
    }
}

實際輸出範例


// Windows 環境
ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\user\AppData\Roaming
CLASSPATH=.;C:\java\lib
COMMONPROGRAMFILES=C:\Program Files\Common Files
COMPUTERNAME=DESKTOP-ABC123
JAVA_HOME=C:\Program Files\Java\jdk-17
NUMBER_OF_PROCESSORS=8
OS=Windows_NT
PATH=C:\Windows\system32;C:\Windows;C:\Program Files\Java\jdk-17\bin
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 158 Stepping 10, GenuineIntel
TEMP=C:\Users\user\AppData\Local\Temp
USERNAME=user
USERPROFILE=C:\Users\user
WINDIR=C:\Windows

// Linux/Docker 環境
HOME=/root
HOSTNAME=container-abc123
JAVA_HOME=/usr/lib/jvm/java-17-openjdk
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/app
TERM=xterm

常見應用場景

1. 設定檔外部化(十二要素應用)


public class Config {
    // 必要變數:不存在拋出異常
    public static final String DB_URL = requiredEnv("DB_URL");
    public static final String DB_USER = requiredEnv("DB_USER");
    public static final String DB_PASS = requiredEnv("DB_PASS");
    
    // 可選變數:提供預設值
    public static final int PORT = Integer.parseInt(optionalEnv("PORT", "8080"));
    public static final String ENV = optionalEnv("ENV", "development");
    
    private static String requiredEnv(String key) {
        String value = System.getenv(key);
        if (value == null || value.isBlank()) {
            throw new IllegalStateException("環境變數 " + key + " 未設定");
        }
        return value;
    }
    
    private static String optionalEnv(String key, String defaultValue) {
        String value = System.getenv(key);
        return (value != null && !value.isBlank()) ? value : defaultValue;
    }
}

2. 區分執行環境


String env = System.getenv("ENVIRONMENT"); // development, staging, production
boolean isProd = "production".equalsIgnoreCase(env);
boolean isDocker = System.getenv("DOCKER_CONTAINER") != null;
boolean isK8s = System.getenv("KUBERNETES_SERVICE_HOST") != null;

3. 動態調整 JVM 參數(容器感知)


// Kubernetes Downward API 注入
String cpuLimit = System.getenv("CPU_LIMIT");      // 如 "2000m" = 2 cores
String memLimit = System.getenv("MEMORY_LIMIT");   // 如 "512Mi"

// 轉換為 JVM 參數邏輯...

跨平台編碼與大小寫注意事項

平台鍵名大小寫編碼備註
Windows不區分大小寫系統預設 (CP950/CP1252/UTF-8)System.getenv("path") == System.getenv("PATH")
Linux/Unix區分大小寫通常 UTF-8PATH != Path != path
macOS區分大小寫UTF-8

最佳實務:統一使用大寫鍵名(如 JAVA_HOME),在容器中透過 env 指令驗證實際注入值。

進階:修改當前進程環境變數(僅限當前 JVM)

Java 無標準 API 修改 OS 環境變數,但可透過反射修改 System.getenv() 回傳的 Map(僅影響當前 JVM 後續讀取):


@SuppressWarnings("unchecked")
public static void setEnv(String key, String value) {
    try {
        Map<String, String> env = System.getenv();
        Class<?> cl = env.getClass();
        if (cl.getName().equals("java.util.Collections$UnmodifiableMap")) {
            Field field = cl.getDeclaredField("m");
            field.setAccessible(true);
            Map<String, String> delegate = (Map<String, String>) field.get(env);
            delegate.put(key, value);
        }
    } catch (Exception e) {
        throw new IllegalStateException("無法設定環境變數", e);
    }
}
// 僅供測試用途,生產環境勿用

容器化部署最佳實務

  • 敏感資訊:資料庫密碼、API Key 勿寫入 Dockerfile ENV,使用 Kubernetes Secrets / Docker Secrets / Vault 注入。
  • 配置分離:應用程式碼與配置分離,透過環境變數注入配置。
  • 預設值策略:開發環境提供 .env 檔案(使用 dotenv-java 載入),生產環境強制要求環境變數存在。
  • 驗證啟動參數:應用啟動時檢查必要環境變數,缺失即快速失效。

總結

System.getenv() 是 Java 應用與作業系統/容器環境溝通的橋樑。掌握單一讀取、全量遍歷、跨平台大小寫差異、容器化注入模式,並建立專案統一的 EnvUtils 工具類,能顯著提升應用的可移植性與安全性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved