《Java虚拟机精讲》前两章的一些简单总结

《Java虚拟机精讲》前两章的一些简单总结。

 

一、Java体系结构

1、Java现在发展出来三个版本,分别是JavaSE,JavaEE,JavaME。比如我们在下载Eclipse的时候,针对不同的Java版本会有不同的IDE。

         区别:JavaSE是标准版,包含Java的全部API,也就是基础类库;JavaEE,是企业版,在JavaSE的基础上扩展了web组建,分布式,EJB(EnterpriseJavaBean)组件等;JavaME是精简版,包含部分的API,主要应用于嵌入式领域。

 

2、Java由四部分组成:基础编程语言,基础类库,Java虚拟机,字节码。

         基础编程语言是指Java语言本身。基础类库是Java提供的便于开发的类集。Java虚拟机是Java程序运行的平台。字节码是指,Java程序编译之后的.class文件(其实我也不清楚为什么会包含字节码)。

 

3、Java的特点:体系结构中立、安全性高、多线程、分布式、丰富的第三方开源组件。

         体系结构中立,是指Java的可移植性好。一次编写,多次运行的特定。这主要是因为Java字节码和JVM的特性。因为它是将代码编译成字节码文件,通过JVM来解释执行,而不是像其他语言一样,直接编译成针对于运行主机特点的二进制可执行代码(机器指令)那样。

         安全性高,是指Java程序运行于JVM之中,提供了自动内存管理,自动的废弃指针回收,自动的数组边界检查,类型转换检查,线程安全机制等。

         多线程,是指在多核CPU下的多线程操作。(这个其他语言也完全支持啊)

         分布式,是指Java对分布式和远程操作等的支持。

         丰富的第三方开源组件。

 

二、Java编译原理(简单过程)

1、安装JDK(Java开发包)之后,Java自带的编译器是javac。平时我们使用的Eclipse使用的编译器是ECJ(Eclipse Compile for Java),TomCat对Java代码的编译也使用的是ECJ。还有一个Java编译器是GCJ(GNU Compilefor Java Programming Language)。

         区别:javac编译器是一种全量式编译,意思就是,每次修改代码之后都要对所有代码进行一次编译。而ECJ是一种增量式编译,意思就是,每次修改代码之后,只对修改后的相关代码进行编译。GCJ是一种可以将java代码直接编译成本地机器指令的编译器,意思就是,编译之后的java代码,可以不依附于JVM,而直接可以在主机上运行。

 

2、javac的编译过程,总的来说有四步:

         词法分析:将源码转换成Token序列;

         语法分析:将Token序列转换成抽象语法树;

         语义分析:完善抽象语法树;

         生成字节码文件:将语法树转换成字节码文件(.class文件)。

 

3、Token序列:Token有标记的意思。在java中可以理解为Token序列是一个枚举类型,其枚举常量包含了Java语言中所有的“关键字”“保留字”“操作符”“运算符”等。

 

4、javac的编译过程简单描述     

1)编译启动:编写好源码后,编译器首先会将待编译的源码文件传入到compile()方法中,在compile()中会调用parseFile()方法,在parseFile()方法中会调用parse()方法。最后在parse()方法中会生成一个JavacParse类的对象,通过这个对象最终调用javac的核心编译方法“parseCompilationUnit()”,在这个方法中完成对源码的词法分析和语法分析过程。

2)词法分析:Java中对Token序列的排序规则是按照语法规定而制定的。比如:import关键字后面就是一个标识符,标识符后面是“分号”或者“点号”。所以在词法分析过程中进行Token序列的转换时,是将已经定义好的Token序列与源码文件进行匹配校验,然后转换。词法分析总的来说有三个步骤:

a.转换package序列;

b.转换import序列;

c.转换class本体。

词法分析的每一个步骤结束后,就会进行相应的语法分析。

3)语法分析:将词法分析之后零散的Token按照Java语法规范整合成一个结构化的抽象语法树。按照上面所说的,语法分析也分为三个步骤,分别是:

a.调用qualident()方法解析package语法节点,生成JCIdent语法树(package只有一级目录的时候)或者JCFildAccess语法树(package有多级目录的时候);

b.调用importDeclaration()方法解析import语法节点,生成JCImport语法树;

c.调用classDeclaration()方法解析class语法节点,生成JCClassDEcl语法树。

除了这三个步骤之外,语法分析还有一个步骤就是

d.调用TopLevel()方法,将上面生成的三个语法树组成在一起生成一个JCCompilationUnit语法树。

4)语义分析:语义分析是对语法分析的结果进行进一步的补充和完善。其中包含了以下几个方面:

a.为没有构造方法的类,添加一个无参构造方法;

b.检查变量是否初始化;

c.检查变量类型和值是否匹配;

d.对String类型的常量进行合并处理;

e.检查是否存在不可达语句;

f.检查是否抛出或者catch了可能的异常;

g.解除java语法糖。

对以上存在的几个名词进行解释:

常量折叠操作:一个String变量中如果包含多个常量信息,并通过“+”号组合起来,那么在编译时候,会将这些信息组合成一个字符串,底层最终存在的字符串对象只有一个。

例如:System.out.println(name +"是" + "一个学生");//name是String类型对象

最终会将常量“是”和“一个学生”都包含到name对象中。

java语法糖:也叫糖衣语法,指的是,在计算机语言中添加某种语法,这种语法能使程序员更方便的使用语言开发程序,同时增强程序代码的可读性,避免出错的机会;但是这种语法对语言的功能并没有影响。Java中的泛型,变长参数,自动拆箱/装箱,条件编译,内部类,断言以及JDK7的switch支持字符串,自动关闭资源(在try中定义和关闭)等。语法糖方便了程序员的开发,提高了开发效率,提升了语法的严谨也减少了编码出错误的几率。

 

5)生成字节码文件:通过以上几个步骤,就形成了一个结构化的抽象语法树,javac编译器最后会掉哦那个Gen类的相关方法将这棵语法树转换成符合JVM规范的字节码文件。编译结束。

 

         总结:以上内容是在看了《Java虚拟机精讲》后前两章的简单总结,因为只是简单的看了书中列出的源码,而没有对源码进行完整的分析,所以会存在很多漏洞和理解上的不足。感谢《Java虚拟机精讲》。

         在Java体系结构中,字节码是个神奇的东西,它保证了Java的跨平台特性。因为一旦将源码编译成字节码之后,不论是在window下,还是在linux下,无论是32位还是64位系统,都可以通过相应JVM来执行字节码文件。这也体现了java虚拟机的厉害之处。

         在javac编译器中。一直存在一个问题,就是java语言到底是解释执行型语言还是编译执行型语言。如果说是编译执行的,那么编译之后的.class文件并不能直接在主机运行,还是需要JVM的解释执行。如果说是解释型语言,那么java确实是将源码先全部编译成.class的字节码文件。最后,从网上查了下资料,确定java是一门解释型语言。但是还存在一个神奇的东西就是JIT(just in time)技术。这种技术,将解释执行和编译执行结合起,将常用的代码段(以方法为单位)会直接编程成可执行代码(机器指令),而其他不常用的会进行解释执行。这样就提高了运行时的速度。同时,在上面说到还有一些编译器,比如GCJ,会将源码直接编程成机器指令,从而不依赖JVM的解释执行,可以单独运行。

 

下面是解释型和编译型的区别和特点:

         编译型语言把源程序全部编译成二进制代码的可运行程序。然后,直接运行这个程序。特点:执行速度快、效率高;依靠编译器、跨平台性差。如:C、C++、Delphi、Pascal、Fortran

         解释型语言把做好的源程序翻译一句,然后执行一句,直至结束!解释型语言,执行速度慢、效率低;依靠解释器、跨平台性好。如:Java、Basic、javascript

 

 

 

 

 

你可能感兴趣的:(Java虚拟机)