今天就跟大家聊聊有关深入浅析Java中输出HelloWorld的原理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
我们初学Java的第一个程序是“你好world"
公共类HelloWorld { 公共静态void main (String [] args) { System.out.println(“你好world"); } }
上面程序到底是怎么在屏幕上输出“hello world”的呢?这就是本来要讲解的内容,即System.out.println(“你好world")的原理。
我们先看看System.out.println的流程。先看看系统。java中出来的定义,源码如下:
公共最终类系统{ … 公共静态PrintStream最后=零; … }
从中,我们发现,
(01)是System.java的静态变量。
(02)而出且是PrintStream对象,PrintStream.java中有许多重载的println()方法。
好的,我们知道了出来是PrintStream对象。接下来,看它是如何被初始化的,它是怎么和屏幕输出关联的?
我们还是一步步来分析,首先看看System.java的initializeSystemClass()方法。
1。initializeSystemClass()的源码如下:把出部分标记为红色,
私有静态孔隙initializeSystemClass () { 道具=新属性(); initProperties(道具);//初始化的VM sun.misc.VM.saveAndRemoveProperties(道具); lineSeparator=props.getProperty (“line.separator"); sun.misc.Version.init (); FileInputStream fdIn=new FileInputStream (FileDescriptor.in); FileOutputStream fdOut=new FileOutputStream (FileDescriptor.out); FileOutputStream fdErr=new FileOutputStream (FileDescriptor.err); 开始(新BufferedInputStream (fdIn)); setOut0(新PrintStream(新BufferedOutputStream (fdOut, 128),真的)); setErr0(新PrintStream(新BufferedOutputStream (fdErr, 128),真的)); loadLibrary (“zip"); Terminator.setup (); sun.misc.VM.initializeOSEnvironment (); 当前线程=Thread.currentThread (); current.getThreadGroup阀门()(当前); setJavaLangAccess (); sun.misc.VM.booted (); }
我们只需要关注上面的红色代码部分:即
FileOutputStream fdOut=new FileOutputStream (FileDescriptor.out); setOut0(新PrintStream(新BufferedOutputStream (fdOut, 128),真的));
将这两句话细分,可以划分为以下几步:
第1步FileDescriptor fd=FileDescriptor.out;
第2步FileOutputStream fdOut=new FileOutputStream (fd);
第3步BufferedOutputStream bufOut=new BufferedOutputStream (fdOut, 128);
第4步PrintStream ps=new PrintStream (bufOut,真);
第5步setOut0 (ps);
说明:
(01)第1步,获取FileDescriptor.java中的静态成员,外面是一个FileDescriptor对象,它实际上是“标准输出(屏幕)”的标识符。
FileDescriptor.java中与FileDescriptor。出相关代码如下:
私有静态原生空隙setOut0 (PrintStream);
从中,我们发现setOut0()是一个本地本地方法。通过openjdk,我们可以找到它对应的源码,如下:,
JNIEXPORT空白JNICALL Java_java_lang_System_setOut (JNIEnv * env、jclass cla jobject流) { jfieldID fid=(* env)→GetStaticFieldID (env, cla,“out",“Ljava/io/PrintStream;“); 如果(fid==0) 返回; (* env)→SetStaticObjectField (env, cla, fid,流); }
说明:
这是个JNI函数,我们来对它进行简单的分析。
(01)函数名
JNIEXPORT空白JNICALL Java_java_lang_System_setOut0 (JNIEnv * env, jclass cla, jobject流)
这是JNI的静态注册方法,Java_java_lang_System_setOut0 (JNIEnv * env, jclass cla, jobject流)会和系统。java中的setOut0 (PrintStream)关联,而且,参数流对应参数。简单来说,我们调用setOut0(),实际上是调用的Java_java_lang_System_setOut0 ()。