System.getenv()和System.getProperty()是Java种常用的两种读取环境配置信息的方法,它们都是java.lang.System类的方法,用途有相似之处,但我们在实际使用中,需要更加注意二者的区别。
System.getenv()读取的是当前系统环境的环境变量。要深入理解环境变量的本质,需要对系统父子进程关系有更加清晰的认识。一般来说,子进程在创建时,会将父进程当时的环境变量复制一份,而父进程中之后发生的环境变量的变动,不会影响子进程中对应的环境变量。
当不传入参数时,System.getenv()的返回值为一个只读的Map,其中包括当前环境下所有环境变量。下面的例子中,我们将打印出这条语句执行时环境中所有的环境变量和它们对应的值,在 windows 中是 用户环境变量和系统环境变量的值,
System.getenv().forEach((key, value) -> {
System.out.println(key + ":" + value);
});
注意:通过 System.getenv()
获取的 Map 是不支持修改的,为了有更深入的理解,我们熟悉下这块的代码
public static java.util.Map<String,String> getenv() {
// ......
return ProcessEnvironment.getenv();
}
ProcessEnvironment.getenv()
该方法的核心逻辑如下,从以下代码中可以看出,返回的 map 是通过Collections.unmodifiableMap()
处理的,因此,返回的map 是不能被修改的。
final class ProcessEnvironment extends HashMap<String,String>{
private static final Map<String,String> theUnmodifiableEnvironment;
static {
theEnvironment = new ProcessEnvironment();
theUnmodifiableEnvironment
= Collections.unmodifiableMap(theEnvironment);
}
// Only for use by System.getenv()
static Map<String,String> getenv() {
return theUnmodifiableEnvironment;
}
}
一般我们在程序中使用时,一般不会获取全部的系统环境变量,因而可以通过 System.getEnv(key)
获取对应环境变量的值。
public static String getenv(String name) {
// .....
return ProcessEnvironment.getenv(name);
}
通上,通过 System.getProperty(key)
获取单个变量值,通过System.getPropertys()
获取所有 JVM 环境变量值。如下
System.getProperties().forEach((k,v) -> {
System.out.println(k + "=" + v);
});
这里列出一些常见的
// classpath
sun.boot.class.path=C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;....
java.library.path=C:\Program Files\Java\jdk1.8.0_131\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;
file.separator=\
sun.jnu.encoding=GBK
java.version=1.8.0_131
java.vm.info=mixed mode
当我们通过 启动JVM时,可以通过 -D 设置JVM 环境变量值,在我们的程序中我们也可以通过,System.setProperty(key,value)
设置JVM 环境变量,该值在整个JVM 间是共享的。
最近线上大数据 Hadoop 集群开启了Kerberos,为了让业务尽量不改动代码的原则,通过 System.getenv()
和 System.getenv()
实现了业务代码零改动下,使用开启Kerberos后的集群。
通过 System.getenv()
和 getProperty()
可以简化我们的有些配置,相比于 xml 等配置文件,这种方式更轻量,如果我们的程序中没有配置文件,但想使某一两项功能实现可配置,通过System.getenv()
和 getProperty()
可以非常容易的实现。