要在JVM中执行java代码必须要编译为class文件,JDK是如何将Java代码编译为class文件,这种机制通常被称为Java源码编译机制。

1、JVM定义了class文件的格式,但是并没有定义如何将java源码编译为class文件,各个厂商在实现JDK时候通常会将符合java语言规范的源码编译为class文件的编译器,如JDK就是javac

javac编译生成class文件的步骤如下:

1、分析和输入到符号表 (Parse and Enter )

Parse过程所做的为词法和语法分析,词法分析(com.sun.tools.javac.parser.Scanner)要完成的是将代码字符串转变为token序列(例如Token.EQ(name:=));语法分析(com.sun.tools.javac.parser.Parser)要完成的是根据语法由token序列生成抽象语法树。

Enter(com.sun,tools,javac.comp.Enter)过程为将符号输入到符号表,通常包括确定类的超类型和接口,根据需要添加默认构造器,将类中出现的符号输入类自身的符号表中等。

2、注解处理(Annotation Processing)

该步骤主要用于处理用户自定的Annotation,可能带来的好处是基于annotation来生成附加的代码或进行一些特殊的检查,从而节省一些共用的代码的编写,例如当采用Lombok时,可大大减少代码量,编译是引入Lombok对实体进行编译后,再通过javap查看class文件,发现自动成get set toString等方法,此功能基于JSR269,在JDK1.6中提供支持,在Annotation Processing进行后,再次进入Parse and Enter步骤

3、语义分析和生成class文件(Analyse and Generate)

Analyse步骤基于抽象语法树进行一系列的语法分析,包括将语法树中的名字,表达式等元素与变量,方法,类型等联系在一起,检查变量使用前是否声明,推导泛型方法的类型参数,检查类型匹配性,进行常量折叠;检查所有语句都可到达,检查所有checked exception都被捕捉或者抛出,检查变量的确定性赋值(如有返回值的方法必须定有返回值);检查变量的确定性不重复赋值(例如声明为final的变量);解除语法糖(消除if(false) )形式的无用代码;将泛型Java转为普通的Java,将含有语法糖的语法树改为含有简单语言结构的语法树,例如for each循环,自动装箱,拆箱等

在完成语义解析后,开始生成class文件(com.sun.tools.javac.jvm.Gen)生成的步骤,首先将实例成员初始化器手机到构造器中,将静态成员初始化器手机为<cinit>();接着将抽象语法树生成字节码,采用的方法为后序遍历语法树,并进行最后的少量代码转换(例如String相加转变为StringBuilder操作);最后从符号表生成class文件。

生成class文件除了javac之外,还可以通过ECJ(Eclipse compiler for java) 或者是Jikes等编译器来将Java源码编译为class文件。

class文件不仅仅存放了字节码,还存放了很多辅助JVM来执行class的附加信息,一个class文件包括

-结构信息

包括class文件格式版本号及各部分的数量和大小信息

-元数据

简单的说可以认为是方法信息对用的java源码中语句,表达式对应的信息,主要有字节码,异常处理表,求值栈与局部变量区大小,求值栈的类型记录,调试用符号信息。

可以通过javac  -g HelloWord.java 编译生成class文件,然后通过javap -c -s -l -verbose HelloWord来查看编译后的class文件。

class文件是完整的自描述文件,字节码在其中只占了很小的部分,源码编译为class文件后,即可放入到jvm中执行,执行时jvm首先要做的是装载class文件,这个机制通常称为类加载机制。

【java】之java代码的执行机制的更多相关文章

  1. java中的代码块执行顺序

    /* 代码块:在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为 局部代码块:局部位置,用于限定变量的生命周期. 构造代码块:在类中的成员位置,用{}括起来的代码.每次 ...

  2. Java类中代码的执行顺序 静态代码块>构造代码块>构造方法

    一:静态代码块 注意是代码块,不是静态函数.函数要调用才执行,代码块加载就执行,一般是静态变量的声明与初始化.被static修饰的代码块(赋值.输出操作等).类中静态语句块仅在类加载时被执行一次 如 ...

  3. Java static 静态代码块执行分析

    假设有这样一个类: public class Utils { static { Log.i("static","isLoad!"); } public stat ...

  4. Java类编译、加载、和执行机制

    Java类编译.加载.和执行机制 标签: java 类加载 类编译 类执行 机制 0.前言 个人认为,对于JVM的理解,主要是两大方面内容: Java类的编译.加载和执行. JVM的内存管理和垃圾回收 ...

  5. java视频教程 Java自学视频整理(持续更新中...)

    视频教程,马士兵java视频教程,java视频 1.Java基础视频 <张孝祥JAVA视频教程>完整版[RMVB](东西网) 历经5年锤炼(史上最适合初学者入门的Java基础视频)(传智播 ...

  6. 深入浅出的JS执行机制(图文教程)

    前序 作为一个有理想有抱负的前端攻城狮,想要走向人生巅峰,我们必须将我们使用的功法练到天人合一的地步.我在们日常工作中,使用最多的语言就是JavaScript了,为了写出完美的.能装逼的代码,我们必须 ...

  7. Java虚拟机JVM内存分区及代码执行机制

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt230 1.  JVM体系结构 图1 JVM体系结构    方法区:存放JVM ...

  8. java执行机制

    java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码 ...

  9. Java编程的逻辑 (22) - 代码的组织机制

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

随机推荐

  1. 项目报错 exception 'RedisException' with message 'Redis server went away' in XXX

    检查服务器防火墙是否开启redis端口:如果返回no 表没确实没开 firewall-cmd --query-port=6379/tcp 开启:firewall-cmd --add-port=6379 ...

  2. YIT-CTF—社工类

    下载图片

  3. python------Json与pickle数据序列化

    一.json序列化 xml在被json取代,不同平台之间的语言转换,只能处理简单的.复杂的用pickle: pickle只能在python中用,而在Java中json也可以被识别. info = { ...

  4. OSX11.12安装任何来源的软件,在终端中输入

    sudo spctl --master-disable

  5. 从简单的mongodb example 的观察

    https://github.com/no7dw/mongodb-example 这是最基础的连接查询.(branch master) var MongoClient = require('mongo ...

  6. stl本子

    记事本,不要想到奇怪的地方去 迭代器什么的不会玩quq set: #include<set> set<int> quq; quq.insert(qvq); -- 插入 quq. ...

  7. skipper lua 添加luarocks 包管理

    skipper 支持基于lua 的script 扩展,同时设计比较方便的filter模型,让我们可以方便 进行request.response的扩展,结合lua 社区的包我们可以快速的进行新功能的开发 ...

  8. Abstract Data Types in C

    Interface declares operations, not data structure Implementation is hidden from client (encapsulatio ...

  9. 新鲜出炉一份Java面试清单,共200+道题

    一.Java 基础 1.JDK 和 JRE 有什么区别? 答:JRE是java运行时环境,包含了java虚拟机,java基础类库.是使用java语言编写的程序运行所需要的软件环境,是提供给想运行jav ...

  10. 随机重拍与抽样(random_shuffle,random_sample,random_sample_n)

    //版本一:使用内部的随机数生成器 template<class RandomAccessIterator> void random_shuffle( RandomAccessIterat ...