浅谈Java文件被执行的历程

 更新时间:2021年06月01日 09:38:38   作者:糖拌西红柿  
学习java以来,都是以语法,类库入手,最基本的也是最基础的java编译过程往往被我遗忘,先解释一下学习java第一课时,都听到过的一句话,“java是半解释语言”。什么是半解释语言。本文将介绍Java文件被执行的历程。

Java的编译过程

Java程序从源文件创建到程序运行要经过两大步骤

1、源文件由编译器编译成字节码(ByteCode)

2、字节码由java虚拟机解释运行。因为java程序既要编译同时也要经过JVM的解释运行,所以说Java被称为半解释语言("semi-interpreted" language)。

一个例子

下面我们通过一个简单的 OneTest.java,来看一下一个java文件从编译到运行的历程。

Public class OneTest{
    public static void main(String[] args){
          Person one = new Person();
           one.say();
    }
}
Public class Person{
    private String name;

    public void say(){
       System.out.println("I `m a Person");
   }
}

这里是两个java文件,分别是OneTest.java,Person.java

第一步

首先是编译阶段,由JVM编译器,将OneTest.java文件进行编译,得到字节码文件(OneTest.class),这里我们发现,OneTest.java中依赖了Person对象,也就是需要Person.java文件,编译器便会检索Persion.java是否被编译(是否存在Person.class),若不存在,则先编译Person.java,java编译一个类时,如果这个类所依赖的类还没有被编译,编译器会自动的先编译这个所依赖的类,然后引用。

1、如果java编译器在指定的目录下找不到该类所依赖的类的 .class文件或者 .java源文件,就会报“Cant found sysbol”的异常错误。

2、编译后的字节码文件格式主要分为两部分:常量池和方法字节码。
常量池记录的是代码出现过的常量、类名、成员变量(Person.java中的类Person名、name成员变量)等以及符号引用(类引用、方法引用(OneTest.java中的person.say),成员变量引用等);方法字节码中放的是各个方法的字节码。

第二步

然后进行解释运行阶段,这里运行阶段分为两步:类的加载和类的执行

JVM主要在程序第一次主动使用类的时候,才会去加载该类。也就是说,JVM并不是在一开始就把一个程序就所有的类都加载到内存中,而是到不得不用的时候才把它加载进来,而且只加载一次。

1、OneTest类的加载:在类路径下找到编译好的 java 程序中;得到 OneTest.class 字节码文件后,系统就会启动一个 JVM 进程,JVM进程从classpath路径下找到一个名为OneTest.class的二进制文件,将OneTest.class文件中的类信息加载到运行时数据区的方法区中,这一过程叫做类的加载。(只有类信息在方法区中,才能创建对象,使用类中的成员变量)关于类的加载器

2、运行OneTest.java中的main方法:main函数的第一条命令是Persion person = new Person();就是让JVM创建一个Person对象,但是这时候方法区中没有Person类的信息,所以JVM马上加载Person类,把Person类的类型信息放到方法区中。

3、加载完Person类之后,Java虚拟机做的第一件事情就是在堆区中为一个新的Person实例分配内存, 然后调用构造函数初始化Person实例,这个Person实例持有着指向方法区的Person类的类型信息(其中包含有方法表,java动态绑定的底层实现)的引用

4、当使用person.say()的时候,JVM根据person引用找到Person对象,然后根据Person对象持有的引用定位到方法区中Person类的类型信息的方法表,获得say()函数的字节码的地址。

5、执行say方法。

以上就是浅谈Java文件被执行的历程的详细内容,更多关于Java文件被执行的历程的资料请关注脚本之家其它相关文章!

相关文章

  • Java应用注册成Windows服务实现自启的教程详解

    Java应用注册成Windows服务实现自启的教程详解

    这篇文章主要给大家介绍了Java应用注册成Windows服务实现自启的教程,文中有详细的代码示例和图文讲解供大家参考,具有一定的参考价值,需要的朋友可以参考下
    2024-02-02
  • MyBatis使用级联操作解决lombok构造方法识别失败问题

    MyBatis使用级联操作解决lombok构造方法识别失败问题

    这篇文章主要介绍了MyBatis使用级联操作解决lombok构造方法识别失败问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java中sleep()与wait()的区别总结

    Java中sleep()与wait()的区别总结

    因为最近学习时正好碰到这两个方法,就查阅相关资料,并通过程序实现,进行区别总结一下,所以下面这篇文章主要给大家总结介绍了关于Java中sleep()与wait()区别的相关资料,需要的朋友可以参考,下面来一起看看吧。
    2017-05-05
  • Idea中添加Maven项目支持scala的详细步骤

    Idea中添加Maven项目支持scala的详细步骤

    这篇文章主要介绍了Idea中添加Maven项目支持scala,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • springboot prototype设置多例不起作用的解决操作

    springboot prototype设置多例不起作用的解决操作

    这篇文章主要介绍了springboot prototype设置多例不起作用的解决操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java中LinkedList和ArrayList的效率分析

    Java中LinkedList和ArrayList的效率分析

    本文主要介绍了Java中LinkedList和ArrayList的效率分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Java实现矩阵顺时针旋转90度的示例

    Java实现矩阵顺时针旋转90度的示例

    今天小编就为大家分享一篇Java实现矩阵顺时针旋转90度的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Java性能优化之关于大对象复用的目标和注意点

    Java性能优化之关于大对象复用的目标和注意点

    这篇文章主要介绍了Java性能优化之关于大对象复用的目标和注意点,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • JAVA基于PDF box将PDF转为图片的实现方法

    JAVA基于PDF box将PDF转为图片的实现方法

    这篇文章主要介绍了JAVA基于PDF box将PDF转为图片的操作方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-07-07
  • java实现根据ip地址获取地理位置

    java实现根据ip地址获取地理位置

    本文给大家汇总介绍了2种分别使用新浪和淘宝接口,实现根据IP地址获取详细的地理位置的代码,非常的实用,有需要的小伙伴可以参考下。
    2016-03-03

最新评论