我们写的Java代码到底是如何运行的?

程序员小跃

共 3326字,需浏览 7分钟

 ·

2021-08-20 09:29


大家好,我是跃哥。想必读者们大部分都是 Java 开发,但是你知道我们平时写的Java代码到底是如何运行的?一般涉及到这样的话题,有些人肯定会觉得,肯定又是底层,又是源码的,应该不好理解吧?非也非也,今天跃哥就和你去玩耍下。


所以这里先给大家做个声明,这次的分享,是带大家整体上对这个问题有一个认识,不会涉及到源码以及很深的底层问题.!


但是保证你看了直呼过瘾,而且你们也都能看懂,毕竟庆哥的文章一直都是那么的通俗易懂!



开始啦,首先,咱们看这样一段代码:


public class Hello {    public static void main(String[] args) {        System.out.println("hello");    }}


简单吧,然后我们运行,此时我是在IDEA中将其运行:



有没有想过,为什么我们写上上面的代码,然后点击运行就能输出打印hello呢?我们接下来找到我们写的这段代码的源文件:



打开检查一下:



没问题,接下来我们将此段代码复制到我们桌面,并且把代码精简一下,也就是成了这样:



ok,注意我们现在已经把Hello放在了桌面上了,代码也做了简化,就是把注释和包名去掉了,只留下核心部分,到了这里,应该没什么问题吧,应该都是听得懂看的明白的吧,那好,现在问题来了,我要问你一个问题:


请问现在的Hello.java存在于哪里?


你肯定会说,简单啊,不是在桌面上吗?不,我想要的不是这个答案,给你几个选项吧:


  1. CPU
  2. 内存(也就是电脑中的内存条)
  1. 硬盘(电脑中的磁盘,也就是你的C盘,D盘这些)

那好,现在你再来回答我,上述的Hello.java存在哪里?我想看到这里,应该每个人心里都有了自己的答案吧,我觉得这并不是什么难题,只要你看过我之前的文章,你都能回答的对,答案就是硬盘!

我们买电脑,大部分时候也都会注意到电脑的容量大小,这里指的就是我们的硬盘大小,比如我的就是就是1T:


那大家为什么要在意这个呢?说的简单点,容量大了,我可以装的东西就多了,比如可以装更多的软件啊,文件啊,比如图片啊,小电影啊,等等,

反正电脑上的大部分东西,可下载的那些都需要容量来存储,也就是咱这磁盘是咱能接触到的最明显的存储设备,比如我的E盘,大家可以看到,已经爆红了,就是容量不多了,

如果我现在想下载个100G的某系列影片,那肯定装不下了,没容量啦,空间不够用!

同样的,我们写的上述的那个Hello.java也是作为一个文件存在于我们的电脑上,而这些东西说白了,都是存储在我们的硬盘上,此时是存在桌面,而桌面是位于C盘下的,所以咱这文件其实就是存在C盘中的,

但是无论存储在哪个盘,都是在我们电脑中的硬盘当中,比如我这里的硬盘其实就是一块1T的固态硬盘,是我后来分区成以上三个盘的,这些想必大家都懂,所以,我们写的Hello.java文件实质上是存储在我们的电脑硬盘当中!

ok,到了这里,我们搞清楚了,我们刚开始写的这些java源文件是存储在哪里,接下来我们继续!


以上这些操作都没什么问题吧?这一步操作是一个编译的过程,为什么要这样搞,我们紧接着看下面的操作:


上面有一个错误,目的是为了告诉大家,编程的学习要认真,不能马虎,很多自己搞出来的错误都不是啥大问题,很多都是自己粗心大意造成的,

记得,要认真,好了,言归正传,我们上面又使用了java指令去执行Hello.class文件,最后打印输出“hello”,什么意思呢?

注意看了,也就是我们写的后缀是java的叫做java源文件,这个是我们程序员自己写的,也就是这些代码:

public class Hello {    public static void main(String[] args) {        System.out.println("hello");    }}

这些代码,我们看着没啥问题,懂点java的都知道怎么回事,但是,对于电脑来说,它就不认识了,所以中间得有个转换的过程,把我们认识的这些java代码转换成计算机可以认识的代码,所以有这么一张图,大家可以看看:


就是说,我们需要把java源文件编译生成字节码文件,也就是点class文件,这个字节码文件其实是java虚拟机识别的语言,但是我们知道,java是一种跨平台语言,

所谓的跨平台主要就是由java虚拟机来实现,我们只要把字节码文件交给java虚拟机,接下来的就有虚拟机去与相应的底层操作系统打交道,去把相应的字节码文件转换成底层操作系统CPU可以执行的指令,

所以,作为我们,暂时关注到字节码这个层面即可,也就是,你得有字节码,才能交给JVM去执行!

另外再给大家说两点小知识,就是:

  1. javac -version 查看的是JDK的版本
  2. java -version 查看的则是JVM的版本

为什么要说这个,那是因为当我们在命令行窗口执行该指令的时候:


这个时候是会启动一个jvm虚拟机的,其实也好理解,因为我们的字节码文件是需要交给jvm去执行的,现在我们这里的操作就是要执行Hello.class字节码文件的,在这里的输入我们可以直接省略掉后缀名class,直接输入“java Hello”即可!

到了这里我又必须问你一个新的问题了,你说这个Hello.class文件是存储在哪里的?

其实答案显而易见啊,必须还是我们的电脑硬盘中的,也就是此时我们写的java源文件Hello.java以及我们编译生成的字节码文件Hello.class都是存储在我们的电脑桌面,实质就是电脑硬盘当中!

到了这里我就必须在给你们来点干货知识了,你要记住以下这句话:

我们写的程序,要想运行,最终必须加载进内存中,才能被CPU调取执行,而且所有的程序在内存中都是以二进制的形式存在的!

咋样,对以上描述有疑惑吗?

那现在,我们是不是有了字节码文件,于是我们执行“java Hello”去执行该字节码文件,这里的过程需要再次强调下,也就是说,当我们在命令行窗口去执行java指令的时候,

实际上就会启动一个jvm虚拟机,在电脑中是一个进程形式存在的,也就是一旦执行“java”指令,测试就启动了一个jvm进程,此前我们说过了,字节码是jvm能够识别的语言,此时这个jvm就是用来执行我们的这些字节码文件的!

这个时候jvm就会把字节码中的相关类加载进我们的内存中去,这就是类加载器在起作用,想必这个类加载器的概念,大家一定不陌生吧,

也就是此时,原本在我们电脑硬盘中的字节码文件通过java指令启动的jvm,将其加载进内存中去了,你要知道,我们的java代码都是由一个个的类组成的,所以此时就由jvm将我们的字节码class文件加载进内存中了,这其中的具体转换细节暂不讨论!

这里可以稍微透露一下,其实jvm有自己的一套字节码执行引擎,jvm就会基于自己的字节码执行引擎,去执行加载进内存的那些类了,

我们知道,我们的java代码必须有一个主入口,也就是一个“main()”方法,jvm就是从这个main方法开始执行代码,然后一步步的执行下去,需要哪个类,就会使用类加载器去加载对应的类,

因为我们之前的所有java源文件已经被编译生成字节码文件了,需要啥类都直接从这个点class文件中加载即可。

当然,以上内容目前只需了解即可,你只要记住,是jvm把字节码文件从硬盘加载进内存中即可!

ok,以上就是我这次要给大家分享的全部内容了,到了这里,也许你会发现,其实整个文章并没有什么高深莫测的东西,可以说都是一些比较基础的东西,

但是我相信,很多人是没有把这些基础的东西给串联起来的,也没有思考过,我们写的代码,刚开始是存储在哪,又是怎样被加载运行的,一步步的,抽丝剥茧,虽然简单,但是总归也会让你有所收获!

你说是吗?






0、重磅!两万字长文总结,梳理 Java 入门进阶哪些事(推荐收藏)

1、讲真的:我达成了一个优秀的小目标

浏览 42
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报