System.getenv()和System.getProperty()是Java种常用的两种读取环境配置信息的方法,它们都是java.lang.System类的方法,用途有相似之处,但我们在实际使用中,需要更加注意二者的区别。
1. 使用System.getenv()
System.getenv()读取的是当前环境的环境变量。要深入理解环境变量的本质,需要对系统父子进程关系有更加清晰的认识。一般来说,子进程在创建时,会将父进程当时的环境变量复制一份,而父进程中之后发生的环境变量的变动,不会影响子进程中对应的环境变量。
当不传入参数时,System.getenv()的返回值为一个只读的Map,其中包括当前环境下所有环境变量。下面的例子中,我们将打印出这条语句执行时环境中所有的环境变量和它们对应的值。
System.getenv().forEach((key, value) -> {
System.out.println(key + ":" + value);
});
尝试修改这一Map的内容将会抛出UnsupportedOperationException异常。
System.getenv()也可以接受单个String作为输入参数,表示需要获取的环境变量名。若在当前环境中存在这一变量,则以String方式返回其对应的值,否则返回null。因此,在使用System.getenv()时,需要注意处理返回null的情形,否则将很可能会导致NullPointerException异常。
2. 使用System.getProperty()
System.getProperty()读取的是当前用户、系统、JVM等相关信息,以及在运行Java程序时以
java -jar JarName -DpropertyName=value
方式传入的参数。
使用System.getProperty()时,我们需要提供获取不到对应参数时的默认项,就像下面这样:
String log_dir = System.getProperty("log_dir","/tmp/log");
当没有设置log_dir参数时,就将使用默认项/tmp/log,这样保证返回值总是一个String,就避免了对null的处理。
此外,这些Property是可写的,可以用System.setProperty()来进行操作:
System.setProperty("log_dir", "/tmp/log");
3. 二者的对比
经过上述比较,可以将System.getenv()和System.getProperty()的区别归纳为以下几点:
System.getProperty()所获取的Property是可读可写的,而System.getenv()获取的环境变量只可读不可写。
System.getProperty()要求我们提供默认项,而使用System.getenv()时需要考虑null的情况
Property只对Java程序有影响,而环境变量会影响整个平台下的所有应有程序
4. 最后的注意事项
一个关键但容易被忽略的细节是,这两个函数遵循了不同的命名规范。getProperty是典型的驼峰式命名,而getenv则全为小写。在实际使用中需要注意这一点。