system.getproperty()仅读取jvm启动时通过-dkey=value显式传入的系统属性,不读args、环境变量或配置文件;正确写法是java -dkey=value -jar app.jar,-d必须置于java后、主类前,ide中须填入vm options而非program arguments或environment variables。

System.getProperty() 只读取 -D 参数,不读其他启动输入。它专用于获取 JVM 启动时通过 -Dkey=value 显式传入的系统属性,和 main 方法的 String[] args、操作系统环境变量(System.getenv())、配置文件内容完全无关。
怎么传才有效?位置和写法必须严格
命令行中 -D 参数必须放在 java 命令之后、主类或 -jar 之前:
- ✅ 正确:
java -Denv=prod -Dport=8080 -jar app.jar - ❌ 错误:
java -jar app.jar -Denv=prod(JVM 不识别,System.getProperty("env")返回null) - ❌ 错误:
java --Denv=prod -jar app.jar(多了一个短横,被忽略) - ❌ 错误:
java -Denv= prod -jar app.jar(等号缺失或有空格,整个参数失效)
IDE 里别填错地方
在 IntelliJ 或 Eclipse 中,-D 参数要填在 VM options(或 Run Configuration → VM Options)里,不是 Program arguments 或 Environment variables 栏:
- Program arguments → 传给
main(String[] args),System.getProperty()拿不到 - Environment variables → 传给操作系统,要用
System.getenv()读取 - VM Options → 才是 JVM 系统属性的入口,
System.getProperty()能读到
读取时常见坑与安全写法
返回 null 是常态,直接链式调用极易触发 NPE:
- ❌ 危险:
System.getProperty("timeout").equals("5000")(null.equals() 报错) - ✅ 推荐:
"5000".equals(System.getProperty("timeout"))(字符串字面量调用 equals,安全) - ✅ 提供默认值:
System.getProperty("timeout", "3000")(未设或为空时返回 "3000") - ✅ 判断布尔值别用
Boolean.parseBoolean:它对未设置和设为false都返回false,无法区分;建议用"true".equalsIgnoreCase(System.getProperty("debug"))
能读哪些 key?两类来源,查得到才算数
可用的 key 分两类:
- JVM 内置属性:如
os.name、java.version、user.home、file.separator,各 JDK 版本基本一致 - 用户自定义属性:仅限你用
-Dkey=value显式传入的,比如-Dlog.level=warn→System.getProperty("log.level") - 运行时查全量:
System.getProperties().list(System.out)(调试用,勿上线) - 注意:
user.dir是启动目录,不是 jar 包所在路径;sun.java.command可读完整启动命令,但 OpenJDK 17+ 默认禁用,需额外加--add-opens











