JVM进阶之字节码文件概述
Posted ProChick
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM进阶之字节码文件概述相关的知识,希望对你有一定的参考价值。
1.字节码文件的跨平台性
-
Java语言被称为跨平台的语言,当Java源代码成功编译成字节码后,如果想在不同的平台上面运行,则无须再次编译。但现如今很多语言,如:Python、php、 Perl、Ruby、 Lisp,几乎都具有跨平台的特性。
-
Java虚拟机被称为跨语言的平台,它只与“.class”这种特定的二进制文件有所关联,所以无论使用何种语言进行开发,只要我们将源代码正确编译成虚拟机所要求的这种二进制文件,那么它就可以在Java虚拟机上运行。
-
要想使一个Java程序正确地运行在JVM中,Java源代码就必须要被编译为符合JVM规范的字节码。
-
前端编译器的主要任务就是负责将符合Java语法规范的Java代码转换为符合JVM规范的字节码文件。
-
javac编译器是一种能够将Java源码编译为字节码的前端编译器,整个过程共经历4个步骤,分别是词法解析、语法解析、语义解析以及生成字节码。
-
2.前端编译器与后端编译器
- 将Java源代码编译为字节码文件的工具就叫做前端编译器,但HotSpot虚拟机并没有强制要求前端编译器只能使用
javac
来编译,其实只要编译结果符合JVM规范即可。除了javac
之外,还有一种被之前经常被用到的前端编译器,那就是内置在Eclipse中的ECJ (EclipseCompiler for Java)编译器。javac
的特点是全量式编译,ECJ
的特点是增量式编译,从编译质量来看它们大体一致,但ECJ
的编译效率会比javac
更加迅速和高效。 - 在JVM中,把热点代码编译成本地机器指令的JIT编译器就叫做后端编译器。一个语言做出的程序是否高效,跟语言本身并没有太大关系,主要有关系的是编译器。Java语言最初没有编译器只有解释器,逐行执行的解释器效率较低,所以后期引入了JIT即时编译器,大大提升了执行效率。
3.从字节码角度分析程序
程序案例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
以上是关于JVM进阶之字节码文件概述的主要内容,如果未能解决你的问题,请参考以下文章