- 1.字节码文件的跨平台性
- 2.前端编译器与后端编译器
- 3.从字节码角度分析程序
- 4.字节码文件解读的方式
-
Java语言被称为跨平台的语言,当Java源代码成功编译成字节码后,如果想在不同的平台上面运行,则无须再次编译。但现如今很多语言,如:Python、PHP、 Perl、Ruby、 Lisp,几乎都具有跨平台的特性。
-
Java虚拟机被称为跨语言的平台,它只与“.class”这种特定的二进制文件有所关联,所以无论使用何种语言进行开发,只要我们将源代码正确编译成虚拟机所要求的这种二进制文件,那么它就可以在Java虚拟机上运行。
-
要想使一个Java程序正确地运行在JVM中,Java源代码就必须要被编译为符合JVM规范的字节码。
-
前端编译器的主要任务就是负责将符合Java语法规范的Java代码转换为符合JVM规范的字节码文件。
-
javac编译器是一种能够将Java源码编译为字节码的前端编译器,整个过程共经历4个步骤,分别是词法解析、语法解析、语义解析以及生成字节码。
-
- 将Java源代码编译为字节码文件的工具就叫做前端编译器,但HotSpot虚拟机并没有强制要求前端编译器只能使用javac来编译,其实只要编译结果符合JVM规范即可。除了javac之外,还有一种被之前经常被用到的前端编译器,那就是内置在Eclipse中的ECJ (EclipseCompiler for Java)编译器。javac的特点是全量式编译,ECJ的特点是增量式编译,从编译质量来看它们大体一致,但ECJ的编译效率会比javac更加迅速和高效。
- 在JVM中,把热点代码编译成本地机器指令的JIT编译器就叫做后端编译器。一个语言做出的程序是否高效,跟语言本身并没有太大关系,主要有关系的是编译器。Java语言最初没有编译器只有解释器,逐行执行的解释器效率较低,所以后期引入了JIT即时编译器,大大提升了执行效率。
程序案例1
// 调用了Integer.valueOf()方法,从缓存数组中返回了一个Integer对象 Integer x = 5; // 定义了一个基本数据类型的5 int y = 5; // 此处虽然是引用类型和基本类型的比较,但是x会进行自动拆箱,最终其实就是x和y的值进行比较 System.out.println(x == y); // true
程序案例2
// Integer中存有一个缓存,范围为-128~127,从字节码中可以看出它们调用了Integer.valueOf方法 Integer i1 = 10; Integer i2 = 10; // 整数10在IntergerCache缓存的范围内,所以返回的是同一个对象 System.out.println(i1 == i2); // true Integer i3 = 128; Integer i4 = 128; // 整数128不在IntergerCache缓存的范围内,所以返回的是新创建的对象 System.out.println(i3 == i4); // false
程序案例3
//此处实质是通过StringBuilder的append方法进行拼接操作,然后通过toString()方法进行new对象
String s1 = new String("hello") + new String("world");
//此处直接定义的是一个字符串常量
String s2 = "helloworld";
System.out.println(s1 == s2); // false
4.字节码文件解读的方式
-
使用Notepad++编辑工具,然后将字节码文件的内容转为16进制形式,或者使用Binary Viewer工具
-
使用JDK自带的javap命令工具
-
使用jclasslib bytecode viewer工具
https://github.com/ingokegel/jclasslib



