在Java开发过程中,有时候须要依据操作系统的类型,来抉择执行不同的脚本或加载不同的动静库,比方 Window下的脚本是 .bat 文件,而 Linux 下的脚本是 .sh 文件,还有 Windows 下的动静库是 .dll 文件,而 Linux 下是 .so 文件。

如果想要晓得以后操作系统的类型,能够通过零碎属性 os.name 来判断,而零碎属性具体是通过 System.getProperty(os.name) 办法获取的,上面先来剖析一下 System 类中的相干源码。

1、System类源码剖析

System 类位于 java.lang 包下,它是一个 final 类,也就示意该类是不能被继承的,它的类定义如下:

public final class System {        /** Don't let anyone instantiate this class */    private System() {    }}

其中构造函数是公有的,不能被实例化。

获取零碎属性的办法是 getProperty(),该办法有两个重载办法,如下:

  • public static String getProperty(String key):其中参数 key 就是属性名;
  • public static String getProperty(String key, String def):参数 key 就是属性名,而参数 def 示意默认值,当指定属性 key 没有值时,应用默认值 def 代替。

上面别离看看这两个办法的源码:

(1)getProperty(String key)

public static String getProperty(String key) {    // 查看属性名    checkKey(key);    // 获取平安管理器    SecurityManager sm = getSecurityManager();    if (sm != null) {        // 查看属性拜访权限        sm.checkPropertyAccess(key);    }    // 获取并返回属性值    return props.getProperty(key);}

获取零碎属性,通常会经验三个步骤:

  • 查看属性名是否为空
  • 查看属性拜访权限
  • 获取属性值

其中 checkKey() 办法源码如下:

private static void checkKey(String key) {    if (key == null) {        throw new NullPointerException("key can't be null");    }    if (key.equals("")) {        throw new IllegalArgumentException("key can't be empty");    }}

该办法次要判断属性名是否为 null 或者为空字符串,如果为 null ,则会抛出 NullPointerException 异样,如果为空字符串,则会抛出 IllegalArgumentException 异样。

SecurityManager 是平安管理器,用于实现安全策略的类,查看应用程序是否具备某些操作的权限,最终会调用 AccessControlContext 类的 checkPermission() 办法,如果应用程序没有操作权限,则会抛出 AccessControlException 异样。

最终属性值的获取是通过 Properties 类的 getProperty() 办法获取的,所有的零碎属性都会保留在 Properties 实例中,由JVM进行初始化,其定义如下:

private static Properties props;private static native Properties initProperties(Properties props);

initProperties() 办法又是在 initializeSystemClass() 办法中调用的,源码如下:

private static void initializeSystemClass() {    props = new Properties();    initProperties(props);  // initialized by the VM    //....}

对于 Properties 类的 getProperty() 办法定义如下:

public String getProperty(String key) {    Object oval = super.get(key);    String sval = (oval instanceof String) ? (String)oval : null;    return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;}

(2)getProperty(String key, String def)

public static String getProperty(String key, String def) {    checkKey(key);    SecurityManager sm = getSecurityManager();    if (sm != null) {        sm.checkPropertyAccess(key);    }    return props.getProperty(key, def);}

该办法和上一个办法的区别在于它能够设置一个默认值,当属性值不存在时,则会应用默认值代替,调用的是 PropertiesgetProperty(String key, String defaultValue) 办法,其定义如下:

public String getProperty(String key, String defaultValue) {    // 首先获取属性值    String val = getProperty(key);    // 如果属性值为 null,则返回默认值    return (val == null) ? defaultValue : val;}

2、代码实现

package com.magic.system;public class SystemUtils {    /**     * 判断操作系统是否是 Windows     *     * @return true:操作系统是 Windows     *         false:其它操作系统     */    public static boolean isWindows() {        String osName = getOsName();        return osName != null && osName.startsWith("Windows");    }    /**     * 判断操作系统是否是 MacOS     *     * @return true:操作系统是 MacOS     *         false:其它操作系统     */    public static boolean isMacOs() {        String osName = getOsName();        return osName != null && osName.startsWith("Mac");    }    /**     * 判断操作系统是否是 Linux     *     * @return true:操作系统是 Linux     *         false:其它操作系统     */    public static boolean isLinux() {        String osName = getOsName();        return (osName != null && osName.startsWith("Linux")) || (!isWindows() && !isMacOs());    }    /**     * 获取操作系统名称     * @return os.name 属性值     */    public static String getOsName() {        return System.getProperty("os.name");    }}

3、测试验证

测试验证代码如下:

public static void main(String[] args) {    System.out.println("os.name : " + getOsName());    System.out.println("isWindows : " + isWindows());    System.out.println("isLinux : " + isLinux());    System.out.println("isMacOs : " + isMacOs());}

在 Windows 10 零碎环境下运行,输入后果如下:

os.name : Windows 10isWindows : trueisLinux : falseisMacOs : false

在 CentOS 7 零碎环境下运行,输入后果如下:

os.name : LinuxisWindows : falseisLinux : trueisMacOs : false