System.getProperty()仅读取JVM启动时用-Dkey=value显式声明的系统属性,不读命令行参数、环境变量或配置文件;必须将-D参数置于-jar前,IDE中需配置在VM Options而非Program Arguments。

System.getProperty() 只认 -D 参数,且优先级高于环境变量。它不会读取命令行参数(--key=value)、配置文件或环境变量,只响应 JVM 启动时显式声明的 -Dkey=value 参数。
必须用 -D,位置和写法不能错
启动命令中 -D 必须放在 -jar 前面,例如:java -Denv=prod -jar app.jar。写成 java -jar app.jar -Denv=prod 会被忽略,System.getProperty("env") 返回 null。常见错误包括:
- 写成
--Denv=prod(多了一个短横) - 漏掉等号,如
-Denv prod(空格分隔 → 整个参数失效) - 值含空格但没加双引号,如
-Dmsg=hello world→ 应写为-Dmsg="hello world"
IDE 中要配在 VM Options,不是 Program Arguments
在 IntelliJ 或 Eclipse 中,-D 参数必须填在 “Run Configuration → VM Options” 栏里。填在 “Program arguments” 里是传给 main(String[] args) 的,System.getProperty() 完全看不到。
Spring Boot 项目同理:若想让 System.getProperty("spring.profiles.active") 生效,必须在 VM Options 里加 -Dspring.profiles.active=dev,而不是用 --spring.profiles.active=dev(后者只进 Spring Environment,不进 JVM 系统属性)。
和 System.getenv() 独立,但可手动组合使用
System.getProperty() 和 System.getenv() 互不感知,没有自动同步。框架常按需合并,比如:
String addr = System.getProperty("rocketmq.namesrv.addr",
System.getenv("ROCKETMQ_NAMESRV_ADDR"));这种写法明确体现优先级:JVM 属性 > 环境变量。注意 System.getProperty(key, defaultValue) 的默认值仅在 key 不存在或值为 null 时生效,不覆盖空字符串。
别混淆 -D 和 -- 参数
--key=value 是 Spring Boot 的命令行参数,由 Spring 解析后注入 Environment,但不会变成 JVM 系统属性。所以 System.getProperty("key") 拿不到,而 environment.getProperty("key") 可以。两者用途不同:-D 面向 JVM 层通用配置(如编码、路径、调试开关),-- 面向应用层业务配置。

















