浅谈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在linux系统下开机启动无法使用sudo命令的原因及解决办法

    java在linux系统下开机启动无法使用sudo命令的原因及解决办法

    每次开机自动启动的java进程,页面上的关机按钮都无法实现关机功能,但是此时如果以chb账号通过ssh登录该服务器,手动杀掉tomcat进程,然后再重新启动tomcat,页面上的关机按钮就有效了
    2013-08-08
  • Java转JSON串的几种方式

    Java转JSON串的几种方式

    本文给大家总结一下java转json串的几种方式,每种方式通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-05-05
  • Java8的常用时间api实用指南

    Java8的常用时间api实用指南

    这篇文章主要给大家介绍了关于Java8的常用时间api的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • springboot3.x版本集成log4j遇到Logging system failed to initialize using configuration from‘classpath:log4问题

    springboot3.x版本集成log4j遇到Logging system failed to initial

    使用Springboot 3.x集成Log4j时可能会遇到版本冲突的问题,这通常可以通过检查Maven依赖树来识别,一旦发现冲突,将Log4j的版本统一更新到最新的兼容版本,例如2.21.1,即可解决问题,此方法有效解决了日志打印错误,是处理类似问题的一个实用参考
    2024-09-09
  • java9新特性Collection集合类的增强与优化方法示例

    java9新特性Collection集合类的增强与优化方法示例

    这篇文章主要为大家介绍了java9新特性Collection集合类的增强与优化方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • 浅谈一下Java中的悲观锁和乐观锁

    浅谈一下Java中的悲观锁和乐观锁

    这篇文章主要介绍了一下Java中的悲观锁和乐观锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Java实现无损Word转PDF的示例代码

    Java实现无损Word转PDF的示例代码

    本文将利用Java中的两个jar包:pdfbox和aspose-words实现无损Word转PDF功能,文中的示例代码讲解详细,感兴趣的小伙伴可以动手尝试一下
    2022-06-06
  • 编写调用新浪微博API的Java程序来发送微博

    编写调用新浪微博API的Java程序来发送微博

    这篇文章主要介绍了编写调用新浪微博API的Java程序来发送微博的方法,只是展示了一个基本的程序框架而非一个完整的图形化软件:)需要的朋友可以参考下
    2015-11-11
  • mybatisplus的逻辑删除问题

    mybatisplus的逻辑删除问题

    这篇文章主要介绍了mybatisplus的逻辑删除问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Seata AT模式启动过程图文示例详解

    Seata AT模式启动过程图文示例详解

    这篇文章主要为大家介绍了Seata AT模式启动过程图文示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09

最新评论