被忽视的 java-D

在 nexus-public 项目中,使用了脚本将多个项目进行文件的打包处理,在启动过程中发现少了配置参数,便难以启动,于是顺便做了一个笔记如下:
在 Java 中,命令行参数 -D 用于设置 系统属性(System Properties),其解析和处理由 Java 虚拟机(JVM)自身在启动时直接完成,而不是由 Java 标准库或应用程序代码处理。以下是详细解析:


1. -D 参数的作用

通过 -D 定义的参数会被 JVM 解析为 系统属性,格式为:

java -D<key>=<value> -jar your-app.jar

例如:

java -Dserver.port=8080 -Dlogging.level.root=INFO -jar app.jar

这些属性会存储在 JVM 的全局系统属性表中,应用程序可以通过 System.getProperty() 访问:

String port = System.getProperty("server.port"); // 返回 "8080"

2. -D 参数的解析过程

阶段 1:JVM 启动时解析
  • 责任方:JVM 的本地代码(C/C++ 实现)。
  • 触发时机:在 JVM 初始化阶段解析命令行参数。
  • 解析逻辑
    1. JVM 遍历所有命令行参数。
    2. 当发现以 -D 开头的参数时,提取其后的 <key>=<value> 对。
    3. 将键值对存入 JVM 内部的系统属性表(System Properties)。
阶段 2:Java 程序访问
  • Java 接口:通过 System.getProperty()System.getProperties() 访问。
  • 底层实现:JVM 通过本地方法(Native Method)从系统属性表中读取值。

3. 关键代码位置(JVM 源码)

虽然 JVM 的具体实现因版本和厂商(如 OpenJDK、Oracle JDK)而异,但核心逻辑在以下文件中:

  • OpenJDK 源码
    • 文件路径:src/hotspot/share/runtime/arguments.cpp
    • 函数:Arguments::parse_each_vm_init_arg()
    • 代码片段:
      if (match_option(option, "-D", &tail)) {
        // 解析 -Dkey=value
        JavaVMOption option;
        option.optionString = create_string_value(tail);
        add_property(option); // 将属性添加到系统属性表
      }
      

4. 系统属性与程序交互

Java 代码访问系统属性
// 获取单个属性
String value = System.getProperty("key");

// 获取所有属性
Properties props = System.getProperties();
props.list(System.out);
覆盖系统属性
  • 启动时覆盖
    java -Dkey=new_value -jar app.jar
    
  • 运行时覆盖(不推荐,需安全权限):
    System.setProperty("key", "new_value");
    

5. 与其他参数的区别

参数类型示例解析方用途
JVM 标准参数-Xmx1024mJVM 自身控制 JVM 行为(如内存大小)
-D 系统属性-Dconfig.file=app.propertiesJVM 自身传递应用程序配置
程序自定义参数--port=8080应用程序自行解析业务逻辑参数

6. 常见问题

Q1:为什么 -D 参数在程序启动后才能访问?
  • 因为 JVM 在启动时才会解析命令行参数并初始化系统属性表,程序启动后属性表已固定。
Q2:能否在运行时动态添加 -D 参数?
  • 不能。系统属性在 JVM 启动后不可修改(除非通过 System.setProperty(),但受安全策略限制)。
Q3:-D 参数和环境变量(Environment Variables)的区别?
  • 系统属性:由 JVM 管理,通过 System.getProperty() 访问。
  • 环境变量:由操作系统管理,通过 System.getenv() 访问。

总结

  • -D 参数由 JVM 直接解析,将键值对存入系统属性表。
  • 系统属性通过 System.getProperty() 访问,是 Java 程序配置的常用手段。
  • 底层实现依赖 JVM 的本地代码(C/C++),而非 Java 标准库。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值