System.getProperty()用于获取JVM启动时加载的系统属性,而非操作系统环境变量;它返回os.name、java.version等内置属性或-D参数指定的自定义属性,常用于跨平台适配与运行时配置。

System.getProperty() 是 Java 中获取 JVM 启动时加载的系统属性(system properties)的标准方式,它不等同于操作系统环境变量(如 PATH、HOME),而是 JVM 自身维护的一组键值对,常用于跨平台适配、调试开关、路径定制和运行时策略切换。
常用系统属性及典型用途
以下属性无需额外设置,JVM 启动时自动注入,可直接读取:
-
os.name:返回操作系统名称(如
"Windows 10"、"Linux"、"Mac OS X"),可用于条件化文件路径分隔符或本地库加载逻辑; -
os.arch:返回 CPU 架构(如
"amd64"、"aarch64"),配合os.name可精准选择 native 依赖; - java.version 和 java.vendor:判断 JDK 版本与厂商(如是否为 OpenJDK 或 Oracle JDK),避免特定版本 bug;
- user.home、user.dir、java.io.tmpdir:分别对应用户主目录、当前工作目录、JVM 临时目录,适合构建可移植的配置/缓存路径;
-
file.separator 和 path.separator:比硬编码
"/"或";"更安全,适配不同系统。
如何安全读取并用于参数动态调整
直接调用 System.getProperty(key) 可能返回 null(键不存在),建议始终提供默认值或做空检查:
- 使用带默认值的重载:
System.getProperty("my.config", "default_value"); - 对布尔型开关,推荐封装工具方法:
boolean debugMode = Boolean.parseBoolean(System.getProperty("app.debug", "false"));
注意:Boolean.parseBoolean()对非"true"(忽略大小写)一律返回false,比== "true"更健壮; - 数值类属性需手动解析,并捕获
NumberFormatException,例如:
int poolSize = Integer.parseInt(System.getProperty("db.pool.size", "8"));
如何在启动时传入自定义系统属性
通过 JVM 参数 -Dkey=value 注入,优先级高于代码中 System.setProperty() 的运行时修改(后者仅影响当前 JVM 实例):
立即学习“Java免费学习笔记(深入)”;
- 命令行示例:
java -Dapp.env=prod -Dlog.level=warn MyApp; - IDE 运行配置中,在 VM options 栏添加(IntelliJ:Run → Edit Configurations → VM Options);
- Maven 命令中可结合
exec:java使用:mvn exec:java -Dexec.args="-Dapp.mode=dev"; - Docker 启动时可通过
java -D...写入 entrypoint,或利用ENV JAVA_TOOL_OPTIONS="-D..."(注意该变量会影响所有 JVM 进程)。
与环境变量(Environment Variables)的区别与协作
System.getProperty() 不读取操作系统环境变量。如需访问 PATH 或 MY_API_KEY,应使用 System.getenv("KEY")。两者可组合使用:
- 优先使用系统属性(更可控、可被测试覆盖),环境变量作后备:
String apiKey = System.getProperty("api.key", System.getenv("API_KEY")); - 敏感信息(如密码、密钥)不应通过
-D明文传递(会暴露在进程列表中),而应走环境变量 + 权限管控,或专用配置服务; - 构建可复现的测试环境时,用
-D模拟不同部署场景(如-Dapp.region=cn),比改环境变量更轻量。


















