System.getProperties()无法获取操作系统环境变量,它只返回JVM启动时加载的系统属性;环境变量(如PATH、HOME)必须使用System.getenv()获取,且需注意跨平台大小写敏感性、容器/IDE/服务配置差异及Android不支持等限制。

System.getProperties() 不能获取操作系统的环境变量——它返回的是 JVM 启动时读取的系统属性(java.version、os.name 等),不是 PATH、HOME 这类 Shell 环境变量。
为什么 System.getProperties() 拿不到 PATH 或 USER
Java 的系统属性和操作系统环境变量是两套独立机制:
-
System.getProperties()读的是 JVM 自己维护的键值对,部分来自启动参数(如-Dfile.encoding=UTF-8)或硬编码(如os.arch) - 真正的环境变量(如
PWD、LANG)需通过System.getenv()访问 - 常见误判:看到
System.getProperty("os.name")返回"Linux",就以为getProperty("PATH")也能拿到路径——实际会返回null
正确方式:用 System.getenv() 读环境变量
这是标准且跨平台的获取方式,JDK 1.5+ 支持:
- 获取单个变量:
System.getenv("PATH")(注意大小写:Windows 不敏感,Linux/macOS 敏感) - 获取全部变量:
System.getenv()返回Map,可遍历 - 不支持通过
System.setProperty()修改环境变量——那是 JVM 属性,不影响 OS 层 - 在容器或受限环境中(如某些 Docker 配置、JNLP 启动),
getenv()可能被沙箱策略限制,需检查SecurityManager设置
容易踩的坑:getenv() 在不同场景下的行为差异
看似简单,但实际部署时几个关键点常被忽略:
- IDE 启动时继承的是 IDE 进程的环境变量,不是你终端里
export的——改完.zshrc要重启 IDE 才生效 - Linux systemd 服务中,环境变量默认极简(几乎只有
PATH=/usr/bin:/bin),需显式用Environment=配置项注入 - Spring Boot 应用若用
@Value("${ENV_VAR:default}"),背后走的是 Spring 的环境抽象,优先级顺序是:命令行参数 > 系统属性 > 环境变量 > 配置文件,别误以为它直接调用了getenv() - Android 不支持
System.getenv()(抛UnsupportedOperationException),因为底层没有传统 Unix 环境变量概念
真正要读 HOME 或 MY_API_KEY,跳过 getProperties(),直奔 System.getenv("HOME") 就行。环境变量的生命周期和可见范围,永远取决于进程创建时父进程传了什么,而不是 JVM 自己“猜”出来的。











