博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字节码文件(Class文件)
阅读量:3889 次
发布时间:2019-05-23

本文共 2933 字,大约阅读时间需要 9 分钟。

一、Java的平台无关性实现

       我们知道Java是“与平台无关”的,实现语言无关性的基础就是虚拟机和字节码存储格式:依靠class文件这种统一程序存储格式的字节码文件实现了语言无关性。保证了就算是不同语言,只要通过对应语言的编译器按虚拟机规范编译成class文件,这个class文件就能够被jvm加载。而不同的操作系统通过运行对应版本jvm来载入这个class文件运行,则实现了平台无关性。

二、那我们有必要来了解下字节码文件,还是从程序入手

public class HelloWorld{	public static void main(String []args){		System.out.println("Hello  Java");	}}

三、编译为字节码文件HelloWorld.class

1、十六进制打开的部分展示:可以看出Class文件是一组以8位字节为基础单位的二进制流

cafe babe 0000 0034 001d 0a00 0600 0f090010 0011 0800 120a 0013 0014 0700 15070016 0100 063c 696e 6974 3e01 0003 28295601 0004 436f 6465 0100 0f4c 696e 654e756d 6265 7254 6162 6c65 0100 046d 61696e01 0016 285b 4c6a 6176 612f 6c61 6e67.....

2、重定向输出为txt文件:javap -v HelloWorld > HelloWorld.class.txt,部分展示:

Classfile /C:/Users/asus/Desktop/HelloWorld.class  Last modified 2019-5-22; size 425 bytes  MD5 checksum b6b55b6a43521851a348c690e1e79095  Compiled from "HelloWorld.java"public class HelloWorld  minor version: 0  major version: 52  flags: ACC_PUBLIC, ACC_SUPERConstant pool:   #1 = Methodref          #6.#15         // java/lang/Object."
":()V #2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #18 // Hello Java .....

3、大概了解了字节码文件的格式,那我们重点来解析它:

(1)魔数 :开头4个字节的cafebabe(咖啡宝贝?java的杯子装咖啡的logo),表明这是一个可以被jvm执行的class文件,仅仅通过.class后缀名来辨别文件的类型是不安全的。基于安全考虑,采用魔数标识.class文件。

(2)版本号:第5、6个字节0000表示次版本号,第7、8字节0034表示主版本号。

(3)常量池 :接着就是常量池,首先是常量池的入口,是一个u2类型的数据,代表常量池的数量:这个从txt文件可以一眼看出有28个常量,而且是从1开始。从第9个字节1d是十六进制,转为10进制就是29,0位空出来了表示null,所以是28个常量。 

常量池里存放的是字面常量(literal)和符号引用(symbolic references),字面量比较接近java中常量的概念,如文本字符串,声明为final的常量值等。符号引用属于编译原理方便的概念,包含以下三个常量; 

    3.1 类和接口的全限定名 
    3.2 字段的名称和描述符 
    3.3 方法的名称和描述符

   每一个常量都是一个表,或者说都有他们自己的结构,所有常量结构的共同点是它们的第一位都是一个u1类型的标志位,用来标志这个常量的类型。

    分析一个常量:第十个字节是0a-->10,这个是常量的标志类型,查表10(常量池的项目类型表 ):  表示类中方法的引用。看txt文件也可以知道: #1 = Methodref          #6.#15         // java/lang/Object."<init>":()V ,这个常量分析我没有深究,就此结束。

(4)在常量池结束之后,紧接着是两个字节代表访问标志:识别这个Class是类还是接口,是不是public类型等等,查表可知。

(5)类索引,父索引和接口索引集合都按顺序排在访问标志之后。

(6)字段表集合:类级变量和实例化变量,包括作用域、修饰符等信息。

(7)方法的表集合:访问标志和名称索引,描述符索引和属性表集合等。

(8)方法中的代码在Code属性中,这也是最重要的一个属性,看txt文件,如下:

{  public HelloWorld();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=1, locals=1, args_size=1         0: aload_0         1: invokespecial #1                  // Method java/lang/Object."
":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String Hello Java 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 3: 0 line 4: 8}

首先是默认自带的无参构造方法,然后是main()方法。

(9)最后是输出:SourceFile: "HelloWorld.java"

 

 

转载地址:http://xophn.baihongyu.com/

你可能感兴趣的文章
epoll模型讲解/源码分析
查看>>
ELF格式与bss段
查看>>
java继承 long和float小记点
查看>>
记录几点在开发中遇到的问题 2015-7-28 (会更新)
查看>>
网银在线的异步操作代码示意图
查看>>
火狐Firefox浏览器安装Selenium_IDE的步骤以及其使用规则
查看>>
记录运行代码的时间长短
查看>>
关于yii2的一些知识的学习笔述
查看>>
用纯php实现MVC框架,文件目录模仿yii2
查看>>
新开发的体重管理项目----用纯php模仿yii2框架建立的
查看>>
JavaScript面向对象编程指南 的笔记
查看>>
在 2016 年做 PHP 开发是一种什么样的体验?(一)
查看>>
PHP获取客户端的IP
查看>>
从头开始学习yii2---1.搭建yii2开发环境
查看>>
从头开始学习yii2---3.语言包的配置
查看>>
yii2-表单验证的一些规则
查看>>
索引相关问题
查看>>
php面试可能会被问道的技术题汇总
查看>>
php面试题1-线程和进程的区别(顺带提下协程)
查看>>
php面试题2-用到过的传输协议
查看>>