没了IDE,你的Java项目还能Run起来吗~

计算机只能识别机器码0101...编程语言->能执行的机器码 须要通过 预处理->编译->汇编->连接->机器码过程。一个语言处理系统的示意图以下:java

编译器 是将源语言程序一次性翻译成一个等价的,用目标语言编写的程序。还存在另外一种常见的语言处理器,解释器:它是逐个语句的执行源语言程序。由一个编译器产生的目标语言程序一般比一个解释器快,但解释器的错误诊断效果一般更好。编程

Java语言处理器结合了编译和解释的过程。一个.Java源程序首先被编译为.class字节码文件,被加载到虚拟机中,而后由虚拟机将字节码翻译成机器码。安全

虚拟机的好处在于:一旦一个程序被转换成 Java 字节码,那么它即可以在不一样平台上的虚拟机实现里运行。实现一次编写,处处运行。另一个好处是它带来了一个托管环境。这个托管环境可以代替咱们处理一些代码中冗长并且容易出错的部分,如自动内存管理与垃圾回收。编程语言

在Hotspot中,虚拟机翻译字节码有两种方式:工具

1.解释执行
即逐条将字节码翻译成机器码并执行。spa

2.即时编译
即将一个方法中包含的全部字节码编译成机器码后再执行。插件

前者的优点在于无需等待编译,然后者的优点在于实际运行速度更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译二者的优势。它会先解释执行字节码,然后将其中反复执行的热点代码,以方法为单位进行即时编译。命令行

即时编译创建在程序符合二八定律的假设上,也就是百分之二十的代码占据了百分之八十的计算资源。翻译

好了,装X结束。3d

阿姨知道的编译知识全在上面了。。(っ╥╯﹏╰╥c)

如题,下面咱们来看一下让Java项目运行起来咱们能作什么。

咱们能作的很简单,固然不是写虚拟机。咱们只须要:

1.执行command javac,将.Java文件变为.class文件。
2.执行command java,让.class文件运行起来。

也就是 执行command :)

Java程序的运行方式

Java程序能够经过java命令运行.class文件运行可执行Jar文件
咱们先看第一种方式:从Hello World开始。

运行.class文件

Step1:编写Java文件

Step2:执行 command javac

将.Java文件变为.class文件

小贴士:class文件的全路径名是包名目录+ 类文件名。

Step3:执行 command java

运行.class文件

神奇,咱们没有用IDE让Java程序运行起来了 :)

小伙伴先别喷老阿姨,哪特么有这么简单的Java项目啊。。咱们工做中用的明明都是Jar文件啊...
Jar文件咋运行啊!!

运行可执行Jar文件

Jar文件是基于ZIP文件格式的一种文件格式,它将大量的Java类文件、相关的元数据和资源(文本、图片等)文件聚合到一个Jar文件中,此外还包含一个可选的META-INF文件夹。这个文件夹下的文件或文件夹主要用来打包和扩展配置信息,包括安全,版本,扩展程序和服务等。如MANIFEST.MF文件定义了扩展和打包的相关数据信息。
一个Jar文件一般在项目中用做第三方类库使用,也是项目构建的一部分。

生成一个Jar文件大体分为两步:

1.将源文件编译为.class文件

2.经过 command jar命令将.class文件,资源文件等等打成一个文件格式的Jar文件。

咱们以一个SbDemo项目为例来看Jar文件的打包和运行。项目目录结构以下:

Test2.java中调用了Test1.java的方法,

咱们须要先将Test1.java编译并打成一个Test1.jar文件,而后经过Test1.jar将Test2.java编译并打成一个可执行的Test2.jar文件

可执行和不可执行的Jar文件 区别在因而否在Jar文件中指定了main方法的入口,咱们后面再看。

Step1:Test1.java的编译

Step2:将编译后的classes/com/Test1.class文件打成一个Test1.jar包

Java中和jar包相关的命令是jar命令,生成一个jar包咱们须要定义信息文件(manifest-file),它能够定义所生成jar包的classpath类搜索路径,jar包的入口类等等。能够理解为与Jar包相关的元数据配置信息
Step2.1 书写信息文件
这里咱们使用resources/manifest-test1.text文件做为信息文件

是的,Test1.java太简单了,就是打成一个可被他人引用的jar包,信息文件不重要。
Step2.2 执行打包命令

Step3. 编译Test2.java文件
由于Test2.java中引用了com.Test1类,因此咱们须要在编译时指定Classpath路径。
Classpath:顾名思义,是指待编译类依赖的类所在路径位置。咱们能够经过 javac 的 -cp 参数指定。
关于编译时classpath的值优先级以下:

  • 若是没有传入classpath参数,将使用环境变量CLASSPATH的值。(小伙伴不知道环境变量咋查看和设置?去看阿姨的上一篇文章:)
  • 若是没有发现环境变量CLASSPATH,将使用 执行命令的当前文件夹(.)。
  • 若是javac命令行 经过-classpath or -cp参数指定了类路径值,则优先级最高。

这里咱们使用-cp指定Test1.jar所在位置

能够看到classes目录下已经生成了com2/Test2.class文件了。

Step4. 将编译后的Test2.class和它依赖的Test1.jar一块儿打成一个可执行的Jar包
Step4.1 书写信息文件
这时候咱们使用信息文件resources/manifest-test2.text文件指定这些信息

Step4.2 执行Jar包生成命令

能够看到在lib目录下生成了Test2.jar

Step5.运行咱们的可执行Jar

大功告成了,咱们的SbDemo项目Run起来了...

固然实际项目不可能人肉编译,打包。咱们须要经过Maven/Gradle等构建工具,帮助咱们管理代码之间的Jar包依赖,构建,部署...咱们可能大多时候经过点一下IDE就托管了Maven的构建部署命令。

拿Maven举例子,Maven首先定义了一套项目结构,咱们按照它的结构书写代码,引入各个模块所须要的Jar包依赖。而后Maven能够经过本身的生命周期管理项目的清理,构建,打包,部署阶段。每一个阶段有对应的Maven插件执行相应的目标。IDE又整合了Maven,使咱们经过点吧点吧按钮就完成了项目的运行。

可是当一个项目并无按照规范的构建工具结构搭建,或者项目没有成功运行报错时,了解Java实际的编译运行过程会对理解、解决这类问题有所帮助。

好啦,限于篇幅,阿姨先不讲这些年Maven躺过的坑了,有想看的吗?关注,在看,转发三连回应下 >-<


参考资料:
[1].《编译原理》序 (゚´ω`゚)゚
[2].https://time.geekbang.org/column/article/11289

相关文章
相关标签/搜索