Java System类解析
System,顾名思义,是java对于系统操作的一个类,该类被final修饰,不可被继承,接下来我们通过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修饰的registerNatives()方法,System类,Object类、Class类、ClassLoader类、Unsafe类等等,native修饰该方法表示该方法不是由Java语言编写,我们称为本地方法,**本地方法是联系Java程序和底层主机操作系统的连接方法。**该方法的作用为对其他的本地方法进行注册,通俗地理解为,在Java虚拟机需要调用本地方法时,会通过registerNatives()让本地方法链接到调用方。
``
private System() {
}
用final修饰的类以及private修饰的构造方法这种类,因为不能new出对像,里面的方法一般是静态的,有的类会提供获取该类对象的静态方法,却因为final修饰类以及private修饰静态方法,使得该对象只能在内存中存在一份,我们称之为单例模式(有兴趣的小伙伴可以看看其他的设计模式)
接下来小伙伴们看看这三个成员变量
public final static InputStream in = null;
//Scanner input=new Scanner(System.in);
public final static PrintStream out = null;
//System.out.println();
public final static PrintStream err = null;
在jdk官方文档解释中,称这三个变量为标准输 入/出 流,
System.in:“标准”输入流。此流已打开并准备好提供输入数据。通常,此流对应于键盘输入或主机环境或用户指定的另一个输入源。
System.out:“标准”输出流。此流已打开并准备好接受输出数据。通常,此流对应于显示输出或主机环境或用户指定的另一个输出目标。
System.err:“标准”错误输出流。此流已打开并准备好接受输出数据。
通常,此流对应于显示输出或主机环境或用户指定的另一个输出目标。按照约定,该输出流用于显示错误消息或其他信息,即使主输出流(变量out的值)已被重定向到通常不被连续监视的文件或其他目的地,也应立即引起用户的注意。
System.err在其他类中均有体现,在出现错误信息时,系统就会调用该方法将错误信息打印出来,例如,常见的e.printStackTrace(catch语句中异常打印语句),我们可以调用Throwable类来查看
``
//Throwable类中的异常打印语句
public void printStackTrace() {
printStackTrace(System.err);
}
接下来,我们继续来看下一个方法System.exit(int status)
public static void exit(int status) {
Runtime.getRuntime().exit(status);
}
该方法描述为:终止当前运行的Java虚拟机。参数用作状态代码;按照惯例,非零状态码表示异常终止。此方法在类运行时调用exit方法。此方法从不正常返回。在我们需要终止java程序时,我们就可以使用System.exit(0)来终止程序,若参数为-1代表异常终止
该方法调用了Runtime类里的exit方法,在Runtime的exit方法里,我们又发现了Shutdown类的exit方法
//Runtime里的exit方法
public void exit(int status) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkExit(status);
}
Shutdown.exit(status);
}
在Shutdown里的exit方法里,我们发现如下代码:
//Shutdown.exit()部分代码
synchronized (Shutdown.class) {
/* Synchronize on the class object, causing any other thread
* that attempts to initiate shutdown to stall indefinitely
*/
beforeHalt();
sequence();
halt(status);
}
在类对象上同步,造成任何其他线程试图启动关闭以无限期停止,我们就知道了,exit方法最终会执行到Shutdown类的exit方法,并且此代码块被synchronized(同步锁)修饰,当此方法调用时,会一并结束其他线程