【java】之java代码的执行机制

要在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源码中语句,表达式对应的信息,主要有字节码,异常处理表,求值栈与局部变量区大小,求值栈的类型记录,调试用符号信息。

时间: 2024-10-27 07:45:10

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

深入理解JVM_java代码的执行机制01

本章学习重点: 1.Jvm: 如何将java代码编译为class文件. 如何装载class文件及如何执行class文件. jvm如何进行内存分配和回收. jvm多线程:线程资源同步机制和线程之间交互的机制. 3.1 java代码的执行机制 java源码编译机制. 1.三个步骤: 分析和输入到符号表(Parse and Enter) Parse过程所做的为词法和语法分析. 词法分析:将代码字符串转变为Token序列. 语法分析:根据语法由Token序列生成抽象语法树. Enter过程为将符合好输入

Java static 静态代码块执行分析

假设有这样一个类: public class Utils { static { Log.i("static","isLoad!"); } public static void staticCode(){ } public int value; public void noStaticCode(){ } } 在整个程序运行起来时,何时加载这个静态代码块呢?1.当实例化该类时.列:new Utils():2.当调用该类静态方法时.列:Utils.staticCode()

java执行机制

java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码编译机制 类加载机制 类执行机制 Java源码编译机制 Java 源码编译由以下三个过程组成: 分析和输入到符号表 注解处理 语义分析和生成class文件 流程图如下所示: 最后生成的class文件由以下部分组成: 结构信息.包括class文件格式版本号及各部分的数量与大小的信息 元数据.对应于Ja

java代码块执行顺序

1.测试类 public class Demo extends SuperDemo { //静态代码块 static{ System.out.println("this is static block"); } //普通代码块 { System.out.println("this is normal block"); } //默认构造函数 public Demo(){ System.out.println("this is demo constructor

java静态成员变量,静态代码块执行测试

Java  类对象 静态成员变量,静态代码块加载执行顺序. package com.yjm.pro; import java.io.IOException; import java.util.Properties; public class Pro {  public static String url;  public static String username;  public static String password;  public static String classforna

代码在线执行工具(PHP,Java,C++ 等)

http://www.it1352.com/Onlinetools 支持几十种语言的在线运行. 缺点:对请求频率限制太严格了,一分钟不到十次吧...可以清理浏览器 Cookie 之后重新访问.必须用示例中的 Rextester 类作为类名. 可以嵌入到自己网站,比如 Java 嵌入语句如下: <iframe src="http://www.it1352.com/Onlinetools/OnlineCompileCommon/4?c_height=100&r_height=100&a

Java中动态代码块,构造代码块,静态代码块之间的执行顺序

Java中动态代码块,构造代码块,静态代码块之间的执行顺序 /** * Java中动态代码块,构造代码块,静态代码块之间的执行顺序 * @author Administrator * */ class HelloA { public HelloA() { System.out.println("HelloA"); } { System.out.println("I'm A class"); } static { System.out.println("st

Java代码的执行顺序

引言 对于Java的初学者而言,很多时候我们只知道如何写一些基础的代码,但是却不知道为什么,对于一些概念而言,更是停留在一个很模糊的概念上,其实这样是不好的一种学习习惯.所以对于不太清楚的一些概念,自己多敲一敲,或许能更好的掌握. [TOC] 问题 今天要说的问题是,Java中代码的执行顺序,不知道叫这个题目合适不.这里先定义几个类别: 构造方法(如:public className(){--}) 静态代码块(如:static {--}) 类的属性变量(如:ClassA a = new Clas

java基础复习一、代码块执行顺序

1 /** 2 * 代码块执行顺序的测试 3 * 执行顺序 静态代码块>main代码块>构造代码块>构造函数>普通代码块 4 * @author Administrator 5 * 6 */ 7 public class ClassDemo01 { 8 static { 9 System.out.println("这是一个静态代码块"); 10 } 11 { 12 System.out.println("这是一个构造代码块"); 13 } 1