天天看点

Java中的System.out.println到底是什么,而且Java源码中System.java的out是null,为什么可以调用println方法?

在我们接触Java第一个程序时,我们使用了public class和public static void main(String[]) args)以及System.out.println("Hello World")代码,至于public class和public static void main(String[] args)的解释,可以参考另一篇文章主类及main方法,要仔细研究该问题,请在有一定语法基础再细看。

1. System和out

首先,System是java.lang包中的一个类,该类中定义了一个PrintStream类型的常量out,并且赋值为null,如下图。

Java中的System.out.println到底是什么,而且Java源码中System.java的out是null,为什么可以调用println方法?

2. println()

Java中的System.out.println到底是什么,而且Java源码中System.java的out是null,为什么可以调用println方法?

3. 模拟System.out.println()形式

Java中的System.out.println到底是什么,而且Java源码中System.java的out是null,为什么可以调用println方法?

4. static问题

虽然我们实现了System.out.println类似形式方法,也可以打印输出,实现类似的功能。但是我们定义的printlnTest是static修饰的静态方法,static方法可以不用对象,直接调用。假如我们去掉printlnTest前修饰的static修饰符,那么输出结果会怎样呢?

Java中的System.out.println到底是什么,而且Java源码中System.java的out是null,为什么可以调用println方法?

5. 最终原因 

如果System.out是null的话,最后肯定是没法调用PrintStream非静态方法的,而且out是public static final修饰,在赋值null后是没法修改和赋值的,所以out肯定是在哪里有设置。不知道你是否有了解过Java里native标识符修饰的方法,native修饰的方法说明方法实现部分不在当前文件在,而是调用C++的动态链接库,因为Java的底层使用C++编写的,所以在底层与系统硬件打交道时,虚拟机JVM通过C++的动态链接库来实现和操作系统的交互。而且System类的顶部有静态代码块,静态代码块中有registerNative()方法,而且该静态代码块会在程序加载时执行,所以系统会在程序运行前先对out进行操作,实际上out不再等于null。

Java中的System.out.println到底是什么,而且Java源码中System.java的out是null,为什么可以调用println方法?