™技术博客

Java | System.getProperty与System.getenv

2021年6月13日

Java System.getProperty 与 System.getenv 区别

1. 引用

在一个Java应用中java.lang包是自动引入的。这个包包括许多常见的类,如 NullPointerExceptionMathString
Java.lang.System是一个final修饰的类,意味着该类不可被继承,因此所有的方法都是静态的。
接下来我们将以下两个系统方法的差异 reading system propertiereading environment variables;即 getPropertygetenv

2. 使用 System.getProperty()

Java平台使用 Properties对象代表当前系统信息和配置,我们称之为系统参数。
系统参数包括当前用户信息、java运行时的版本信息、文件分隔符(file pathname separator)。
如以下示例代码,我们使用System.getProperty("log_dir")读取属性log_dir的值。我们也可以使用一个默认参数当该属性不存在时,返回/tmp/log

1
String log_dir = System.getProperty("log_dir", "/tmp/log");

运行时更新系统属性,使用System.getProperty()方法

1
System.getProperty("log_dir", "/tmp/log");

我们可以通过命令行参数方式给应用传递我们自己定义的属性或者配置,如

1
java -jar jarName -DpropertyName=value

如 设置foo=bar属性在app.jar中

1
java -jar app -Dfoo="bar"

3. 使用 System.getenv()

环境变量为key/value对,类似于属性值。许多操作系统允许使用环境变量来传递配置信息给应用。
设置环境变量的方式与操作系统有关,例如,Windows系统通过控制面板的系统配置、Unix使用shell脚本。
当创建一个进程时,默认会从父进程中克隆一份环境变量。
如示例代码,通过一个lambda表达式来打印所有的环境变量。

1
2
3
System.getenv().foreach((k, v) -> {
System.out.println(k + ":" + v);
});

getenv返回一个只读Map,当试图给这个Map新增元素时,会抛出UnsupportedOperationException
获取指定环境变量的值

1
String log_dir = System.getenv("log_dir");

从另一方面看,我们可以根据当前应用创建另外一个进程,且在它的环境中增加新的变量。
创建子进程,在Java中可以使用ProcessBuilder类,这个类有个方法用于调用环境变量。该方法返回一个map,但是这个map是并非只读的,可以往里新增元素。

1
2
3
4
ProcessBuilder pb = new ProcessBuilder(args);
Map<String, String> env = pb.environment();
env.put("log_dir", "/tmp/log");
Process process = pb.start();

4. 二者的区别

尽管二者都需要map结果来提供key-value,但是二者还是有一些区别

  • 我们可以在运行时更新Properties,但是环境变量系统变量一个不可变的副本
  • Properties只能包含于Java平台,而环境变量在操作系统层面是全局的,在相同机器上,所有应用都可以使用。
  • Properties当打包应用时必须存储,而环境变量可在任何是有由操作系统来创建。

5. 结论

使用环境变量,相同的应用可以被发布到不同的机器上跑不同的实例。可以在操作系统级别配置,更新配置时无需重新构建应用。

Tags: java

扫描二维码,分享此文章