System类梳理

本文详细介绍了Java中的System类,包括如何使用arrayCopy方法进行数组复制,利用currentTimeMillis和nanoTime获取系统时间,以及如何获取和操作系统环境变量和属性。System类还提供了设置和获取系统属性的API,并且可以调用Runtime的方法如exit、gc等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

System类

不能被实例化
提供了标准输入、标准输出和错误输出流
可以访问外部定义的属性和环境变量
提供加载文件和库的方式
包含一个用于快速复制数组部分元素的工具方法

构造方法私有化

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

注册本地方法

/* register the natives via the static initializer.
*
* VM will invoke the initializeSystemClass method to complete
* the initialization for this class separated from clinit.
* Note that to use properties set by the VM, see the constraints
* described in the initializeSystemClass method.
*/
private static native void registerNatives();
static {
registerNatives();
}

本地方法,通过 关键字 native 来声明,JDK不实现,JVM实现。可以理解为,接口 和 接口的实现类的关系,JDK中声明的native方法 是接口,JVM对native方法的实现 是 接口的实现。

/* Only register the performance-critical methods */
static JNINativeMethod methods[] = {
    {"currentTimeMillis", "()J",              (void *)&JVM_CurrentTimeMillis},
    {"nanoTime",          "()J",              (void *)&JVM_NanoTime},
    {"arraycopy",     "(" OBJ "I" OBJ "II)V", (void *)&JVM_ArrayCopy},
};

#undef OBJ

JNIEXPORT void JNICALL
Java_java_lang_System_registerNatives(JNIEnv *env, jclass cls)
{
    (*env)->RegisterNatives(env, cls,
                            methods, sizeof(methods)/sizeof(methods[0]));
}

初始化System类

/**
* Initialize the system class. Called after thread initialization.
*/
private static void initializeSystemClass() {}

initializeSystemClass 方法用于初始化 Java 系统类,确保在主线程初始化后系统资源和环境配置正确。主要步骤如下:

  1. 初始化系统属性:创建并初始化 Properties 对象,保存系统属性,native方法
  2. 处理内部属性:移除某些仅供内部使用的系统属性。
  3. 设置系统行分割符:line.separator
  4. 设置版本属性
  5. 设置输入输出流:初始化标准输入、输出和错误流。
  6. 加载库和信号处理:加载必要的本地库(如 zip 库),设置 Java 信号处理器。
  7. 初始化操作系统环境:根据需要调整操作系统的配置。
  8. 添加主线程到线程组:将主线程手动添加到其线程组。
  9. 注册共享秘密:设置 JavaLangAccess 接口以访问内部实现。
  10. 标记 JVM 启动完成:通知 JVM 初始化已完成

系统分割符:

file.separator:文件路径分隔符(如 Windows 的 \ 或 Unix/Linux/macOS 的 /)
path.separator:路径列表分隔符(如 Windows 的 ; 或 Unix/Linux/macOS 的 :)
line.separator:行分隔符(如 Windows 的 \r\n 或 Unix/Linux/macOS 的 \n

设置版本属性:

System.setProperty("java.version", "1.8.0_431");
System.setProperty("java.runtime.version", "1.8.0_431-b10");
System.setProperty("java.runtime.name", "Java(TM) SE Runtime Environment");

数组copy

数组,是一个定长的对象。如果需要存储的数据长度 超过 初始定义的长度时,就需要 扩容。将原数组中的数据 copy 到另一个新的数组中。

必须使用 System类提供的 arrayCopy 来完成 数组的copy。

public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

系统时间

public static native long currentTimeMillis();

public static native long nanoTime();

获取环境变量

环境变量是当前系统的,只能读取现有的环境变量的数据

public static java.util.Map<String,String> getenv() {
        SecurityManager sm = getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("getenv.*"));
        }

        return ProcessEnvironment.getenv();
    }


public static String getenv(String name) {
        SecurityManager sm = getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("getenv."+name));
        }

        return ProcessEnvironment.getenv(name);
    }

操作属性变量

对于属性的操作,是System类中 持有 java.util.Properties,也是一种map结构。

设置属性

public static void setProperties(Properties props) {
        SecurityManager sm = getSecurityManager();
        if (sm != null) {
            sm.checkPropertiesAccess();
        }
        if (props == null) {
            props = new Properties();
            initProperties(props);
        }
        System.props = props;
    }


public static String setProperty(String key, String value) {
        checkKey(key);
        SecurityManager sm = getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new PropertyPermission(key,
                SecurityConstants.PROPERTY_WRITE_ACTION));
        }

        return (String) props.setProperty(key, value);
    }

读取属性

public static Properties getProperties() {
        SecurityManager sm = getSecurityManager();
        if (sm != null) {
            sm.checkPropertiesAccess();
        }

        return props;
    }


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

        return props.getProperty(key);
    }


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

        return props.getProperty(key, def);
    }

删除指定属性

public static String clearProperty(String key) {
        checkKey(key);
        SecurityManager sm = getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new PropertyPermission(key, "write"));
        }

        return (String) props.remove(key);
    }

 4个特殊的方法

都是调用Runtime的方法

public static void exit(int status) {
        Runtime.getRuntime().exit(status);
    }

public static void gc() {
        Runtime.getRuntime().gc();
    }


@CallerSensitive
public static void load(String filename) {
        Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
}

@CallerSensitive
public static void loadLibrary(String libname) {
        Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值