良心公众号
关注不迷路
作为一名程序员,当我们编写一段程序之后,当我们按下IDE的运行键之后,在程序的世界里,究竟发生了些什么?这篇文章让我们来一探究竟。
在开始之前,需要说明两个问题:
首先,上述问题针对不同的编程语言,会有一定程度上的不同,本文将以Java编程语言为例,来展开对问题的阐述;
另外,本文将主要讨论像HelloWorld这样“简单的”Java程序,它是怎样跑起来的。何为简单的Java程序?除JDK所提供的依赖包之外,不再引入其他依赖的Java程序,我们在这里将其定义为简单的Java程序。对于Java web程序,其跑起来的过程会更加复杂,我们将在后面的文章中进行讲述。
接下来,让我们开始这篇文章的探索,首先我们看一下这段编程界无人不知,无人不晓的HelloWorld代码:
图1
从图1中的这段程序我们看出,它除了依赖JDK11之外,不依赖任何其他的包。当按下IDE的运行键,会发生什么呢?我们不妨先来看看下面这张图。
图2
图2中的HelloWorld.class文件及其所在的整个目录,是我们按下IDE的运行键所得到的。不仅如此,我们还会看到控制台将会打印如下内容:
"JavaPath\Java\jdk-11.0.7\bin\java.exe" "-javaagent:IDEAPath\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=3273:IDEAPath\JetBrains\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath C:\test\out\production\test HelloWorld
Hello world!
Process finished with exit code 0
我们往往只会注意控制台打印出了Hello world!(因为这是我们期待的程序运行结果),而忽视了它上面这一行信息。而就是这行信息,它包含了这段程序跑起来的关键步骤。
我们一一来看命令行输出的内容:
首先是打印了jdk所在的路径,java编程首先得有jdk,在之前的这个JDK自带的有趣工具,你知道吗?一文中曾经提到过,JDK、JRE和JVM,以及三者之间的关系,在此就不再赘述。
然后是输出了-javaagent参数,这个参数指定的jar包是idea_rt.jar,-javaagent是java命令的一个参数,它指定的是一个jar包,这个jar包相对于普通的jar包有两个要求:jar包的MANIFEST.MF文件必须指定Premain-Class项;Premain-Class指定的类必须实现premain()方法。premain()方法,顾名思义,在main()方法之前运行的方法,听起来是不是很不可思议,main()方法竟然不是最先被运行的!也正因为如此,我们可以通过-javaagent做很多看起来不可思议的事,比如动态修改字节码等。
在大致了解了-javaagent的作用之后,我们把焦点放到idea_rt.jar这个jar包上,它是干什么的呢?Talk is cheap, show me the code! 我们用工具反编译一下,来看看这个jar包到底做了什么。我们按照上文讲述的顺序,先看一下MANIFEST.MF文件中的Premain-Class参数:
图3
通过图3,我们找到了Premain-Class参数的具体值,接下来,我们看一下
com.intellij.rt.execution.application.AppMainV2$Agent的具体内容:
图4
在图4中,我们终于找到了premain()方法,顺着这个路径调用继续找下去,我们会发现,这个jar包是idea用来监控我们编写的应用程序运行的,了解了此用途之后,其余细节在此就不再赘述。
接下来是-Dfile.encoding,该参数反映了文件的编码格式为UTF-8。
再之后是-classpath,该参数说明了生成的class文件的路径,而生成的class文件的内容正是图2所展示的内容!
我们对上述步骤加以梳理,再补充一些细节,便得到了HelloWorld程序跑起来的步骤。
首先,将HelloWorld程序通过javac命令进行编译,得到HelloWorld.class文件。
然后,idea通过java命令的-javaagent参数对将要运行的程序加以监控。
之后,JVM执行class文件,这一过程可以参看每日一面——你对Class文件了解多少?以及每日一面——谈谈你对类加载机制的理解这两篇文章。
总结一下就是,一个简单的HelloWorld程序,在点下IDE的运行键之后,就会开启命运转动的齿轮,JDK像一个生产java程序的工厂,生产出一个又一个class文件,class文件在JVM这一平台上得以运行,在这一过程中,IDE则扮演监控程序执行的作用,在程序正常运行完成之后成功退出,在程序运行出现异常时将错误提示显示在控制台。
今天关于简单的Java程序是如何运行起来的总结就到这里了。
欢迎大家一起讨论技术,共同成长!
学习 | 工作 | 分享
????长按关注“有理想的菜鸡”
只有你想不到,没有你学不到