class和dex

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mingyunxiaohai/article/details/86621283

class文件

概念:可以被JVM识别加载并执行的文件格式。java,scala,kotlin,python,ruby都可以生成class文件

怎么生成class文件:
(1)通过我们的IDE ,build生成
(2)通过javac命令生成
怎么执行class文件
(1)通过IDE中的run执行
(2)通过java命令执行

class文件的作用:记录一个类文件的所有信息

class文件的结构:

  • 一种8位字节的二进制刘文建
  • 各个数据按顺序紧密排列无间隙,减少了文件的体积,加快了加载的速度
  • 每个类或者接口都单独占据一个class文件,每个类单独管理没有交叉。
类型 名称 数量 描述
U4 magic 1 加密段
U2 minor_version 1 最小适配的jdk版本
U2 major_version 1 编译使用的jdk版本
U2 constant_pool_count 1 常量池的数量
cp_info constant_pool constant_pool_count-1 常量池的结构体,常量池
U2 access_flags 1 访问级别,作用域public,private …
U2 this_class 1 当前类
U2 super_class 1 父类
U2 interfaces_count 1 类实现接口的数量
U2 interfaces interfaces_count 当前类直接继承的接口,不包括父类的
U2 fields_count 1 类成员变量的数量
field_info fields fields_count 成员变量
U2 methods_count 1 类方法的数量
method_info methods methods_count 类方法的结构体,方法的名字类型等
U2 attributes_count 1 类属性的数量
attribute_info attributes attributes_count 类属性的结构体,比如注解等

access_flags的取值范围

标志名 标志值 标志含义 针对的对象
ACC_PUBLIC 0X0001 public类型 所有类型
ACC_FINAL 0X0010 final类型
ACC_SUPER 0X0020 使用新的invokespecial语义 类和接口
ACC_INTERFACE 0X0200 接口类型 接口
ACC_ABSTRACT 0X0400 抽象类型 类和接口
ACC_SYNTHETIC 0X1000 该类不由用户代码生成 左右类型
ACC_ANNOTATION 0X2000 注解类型 注解
ACC_ENUM 0X4000 枚举类型 枚举

constant_pool包含:

CONSTANT_Integer_info
CONSTANT_Long_info
CONSTANT_String_info

分别存储类中的int ,long ,String等类型的数据
CONSTANT_Class_info : 类相关信息 ,只保存索引
CONSTANT_Fieldref_info :成员变量相关信息,只保存索引
CONSTANT_Methodref_info:方法相关信息,只保存索引

下面来看一个class文件的内容,在android studio中

public class Hello {
    public static void main(String[] args){
       System.out.print("hello");
    }
}

然后编译就能生成hello的class文件
位置在app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes\com\cxt\hello
使用010Editor(可百度下载安装)打开hello.class文件
在这里插入图片描述
上图中我们就可以看到前面说的那些字段,点击就可以看到每个字段的信息,起始位置,长度大小等

class文件的弊端

内存占用大,不适合移动端
独占加载模式,加载速度慢
文件IO操作多,类查找慢

dex文件

概念:dex是能够被DVM(Dalvik虚拟机 ART虚拟机)识别,并加载的文件格式
dex中包含了app的所有的源码

dex文件生成:
(1)IDE通过build生成
(2)通过dex命令生成

dex记录了整个工程中所有类文件的信息

结构:

  • 一种8位字节的二进制流文件
  • 个呢过暑假按顺序紧密排列无间隙
  • 整个引用中所有的java源文件都放在一个dex中

文件头:head (文件头)
索引区:string_ids(字符串索引),type_ids(类型索引),proto_ids(方法原型索引),field_ids(域的索引),method_ids(方法的索引)
数据区:class_defs(类的定义区),data(数据区),link_data(链接数据区,so文件)

header部分

字段名称 偏移值 长度 说明
magic 0X0 8 dex魔数字段固定信息“dex\n035\0”
checksum 0X8 4 校验码
signature 0XC 20 sha-1签名
file_size 0X20 4 dex文件总长度
header_size 0X24 4 文件头的长度
endian_tag 0X28 4 标示字节顺序常量
link_size 0X2C 4 连接字段的大小,如果是0就是静态连接
link_off 0X30 4 连接字段开始的位置
map_off 0X34 4 map数据基址
string_ids_size 0X38 4 字符串列表中字符串的个数
string_ids_off 0X3C 4 字符串表基址
type_ids_size 0X40 4 类列表里类型的个数
type_ids_off 0X44 4 类列表基址
proto_ids_size 0X48 4 原型列表中原型的个数
proto_ids_off 0X4C 4 原型列表的基址
field_ids_size 0X50 4 字段个数
field_ids_off 0X54 4 字段列表基址
method_ids_size 0X58 4 方法个数
methon_ids_off 0X5C 4 方法列表基址
class_defs_size 0X64 4 类定义标中类的个数
class_defs_off 0X60 4 类定义列表基址
data_size 0X68 4 数据段的大小
data_off 0X6C 4 数据段基址

索引区和数据区都可以通过010Edito0r查看到。还是上面那个Hello工程
dex文件位置:app\build\intermediates\dex\debug\mergeDexDebug\out
使用010Editor打开此文件下的classes.dex文件
在这里插入图片描述
上图就可以看到头部信息,索引区,数据区的信息。

class文件和dex文件对比

  • dex是从class文件演变而来
  • class文件对应java中每一个类,dex文件的头文件与索引区部分,保存了所有类及类中数据的索引,因此,dvm可通过这两部分快速查找到对应类及数据
  • class文件存在许多冗余信息,dex会出去冗余并整合,更适合移动端。

猜你喜欢

转载自blog.csdn.net/mingyunxiaohai/article/details/86621283