Android插件化技术——【class学习】

news2025/3/1 0:02:45

class 文件的定义

class 文件就是能够被 JVM 识别,加载并且执行的文件格式。从定义来看,class 文件没有想象中的那么神秘,和其他格式如 txt,mp4 一样,只是一种文件格式,它存储的是我们应用程序。

不止 Java 语言,很多其他语言,比如 Scala,Python,都可以生成 class 字节码文件,被 JVM 识别和执行。

Class字节码文件分析

文件结构:

Magic:

class文件的魔数,class文件的魔数是一个固定的值:0XCAFEBABE

minor_version major_version:

文件版本号,对应JDK版本。

constant_pool_count和constant_pool:

常量池数和常量,常量池中记录了java文件中的所有的常量类型包括字符串、类名、方法名等,除了JAVA源代码中定义的的常量,常量池中还包含下面几种类型:

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

除此之外常量池还描述了类的引用信息。

总共有如下12种类型:

每种常量类型结构表

Access_flags

它定义了java源文件中类或者接口的类型

this_class

对常量池的索引。在this_class位置的常量池入口必须为CONSTANT_Class表,该表索引指向一个CONSTANT_Utf8,该CONSTANT_Utf8存放该类的全限定名。

super_class

对常量池索引,在super_class位置的常量池入口是一个指向该类超类全限定名的CONSTANT_Class入口,如果该类直接继承自object类,那索引值为0.

interfaces_count和interfaces

由该类自己实现的或者该类继承后扩展的接口。

如何生成一个 class 文件

通常我们有两种方式来生成 class 文件。

第一种方式就是通过我们强大的 IDE 来生成 class 文件,无需我们操心步骤,像 eclipse 和 IDEA 或者是 Android 开发使用的 Android Studio 都是我们常用的可以自动生成 class 字节码文件的 IDE,同时,我们能通过 IDE 来帮助我们执行 class 文件,只需要简单的点击 IDE 中的 run 按钮,即可执行。

虽然强大的 IDE 简化了我们程序员很多操作,方便和提高了我们的开发工作,但同时会让我们难以理解生成 class 文件的真正流程,所以很多小伙伴在刚开始学习 Java 的时候,老师都会建议我们使用终端的 javac 命令去生成 class 文件,通过 java 命令来执行 class 文件。这就是我们的第二种方式。

例如现在控制台所在文件目录下有一个 Test.java 文件,我们通过 javac Test.java 来生成 Test.class 文件,通过 java Test 执行,控制台就能看到输出结果了。

javac 可以指定很多参数,如 -target 1.6 -source 1.6 ,可以指定 JDK 版本,通常我们指定一个比较低的 JDK,JDK版本是向下兼容的,这样我们使用高版本 JDK 时候,也是没有问题的。当然还有别的指令,这里就不再赘述了。

class 文件的作用

class 文件的作用是记录一个类文件的所有信息。这里我们要强调下这个所有信息,因为 class 文件所包含的类文件信息,是远远多余我们能看到的 java 源代码中的信息。

比如说 java 中我们能使用 this、super ,但我们并没有定义这些关键字,这是因为我们在生成 class 字节码的时候,虚拟机帮我们记录了当前类 this 和父类 super 的信息,所以说 class 字节码文件的信息量是远多于 java 源代码的。

class 文件格式详解

class 的文件结构有以下几个特点:

  • class 文件是一种 8 位字节的二进制流文件。
  • 各个数据是按顺序紧密排列的,没有任何间隙,这样可以减少我们 class 文件的体积,让 JVM 加载更加迅速。
  • 每一个类、接口或者枚举等,都会单独占据一个 class 文件,这样的好处可以类和接口等可以独自管理自己的内容而无需相互交叉提升管理的复杂性。

下图是 class 文件的内部结构和所有的字段,我们将会具体解释下每个字段的内容。

  • magic:无符号 4 字节类型,这个字段是 class 文件的加密端,用来检测这个 class 文件有没有篡改过,如果被篡改过了,JVM 将会有一系列的措施。有点类似于 MD5 加密。
  • minor_version:最小 JDK 适配版本。
  • major_version:当前适配的 JDK 版本。
  • constant_pool_count:常量池数量,通常都是 1
  • constant_pool:真正的常量池字段,结构体类型,是我们 class 文件中最核心和也是比较难懂的部分。
  • access_flags:当前 class 文件作用域标志,如 public , private , protected,这个比较好理解。
  • this_class:JVM 帮我们填充的当前类信息。
  • super_class:JVM 帮我们填充的父类信息。
  • interfaces_count:继承的接口数量,只记录直接继承的接口。
  • interfaces:记载继承的接口,数量为 interfaces_count
  • fields_count:标明 class 文件中的成员变量的数量
  • fields:结构体类型,数量为 fields_count,包含成员变量的 Name,所属的类和类型。
  • methods_count:方法数量
  • methods:结构体类型,数量为 methods_count,记录了方法的 name , type , access_flag等信息。
  • attribute_count:以上没有包含的信息的数量。
  • attributes:结构体类型,数量为 attribute_count,比如包含了注解等信息。

class 文件的这种文件结构有点像 JSON,通过这样一层套一层的结构,我们想要查阅什么类信息,都可以查阅的到。我们来看下 access_flags 的取值范围,包括了我们平时使用到的所有类型,如下图所示,不再具体说明:

下面我们将具体的讲解下constant_pool字段。

constant_pool 中有一些比较简单的字段,比如 CONSTANT_Integer_info,CONSTANT_Long_info,CONSTANT_String_info等,这些字段存储了相对应类型的信息,当然还有像 Short,Double 这样的其他类型。

CONSTANT_Class_info 记录了类相关的信息,不仅记录了当前类的信息,如名字和 access_flags,还记录了引用到的类的信息。还有 CONSTANT_Fieldref_info 记录了成员变量的信息,CONSTANT_Methodref_info 则记录了类中方法的信息。这些存储的并不是真正的内容,而是索引,指向之前说的那些CONSTANT_Integer_info,CONSTANT_Long_info,CONSTANT_String_info,真正的内容实际上是存储于这些字段中的。

我们可以通过一个很棒的软件来查看这些二进制文件:010 Editor。 这款软件很强大,作用主要是来查看二进制文件,不仅可以看 class 文件,还能看 dex 文件,非常清晰的能看到这些文件的文件结构。

有关 class 的知识点就简单的介绍到这里,有关更多的Android开发基础或核心进阶技术,可参考《Android核心技术手册》里面记录了大大小小的基础知识和Android进阶的核心必备技术。

文末

Java 能够实现"一次编译,到处运行”,这其中 class 文件要占大部分功劳。为了让 Java 语言具有良好的跨平台能力,Java 独具匠心的提供了一种可以在所有平台上都能使用的一种中间代码——字节码类文件(.class文件)。有了字节码,无论是哪种平台(如:Mac、Windows、Linux 等),只要安装了虚拟机都可以直接运行字节码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/117434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

matlab/simulink中关于如何使得信号FFT和IFFT前后功率保持一致

快速傅里叶变换FFT其实是一种对离散傅里叶变换DFT的快速算法 为了便于公式推导和理解,本文从DFT的公式出发进行解释,在帕萨瓦尔定律的条件下,探究如何保证FFT/IFFT前后信号功率保持一致。 目录模型假设FFT前后功率保持一致IFFT前后功率保持一…

Bluetooth LE相关学习笔记

The Bluetooth LE Specifications The Bluetooth Core Specification 核心规范适用于 Bluetooth LE和Bluetooth Classic,它定义了蓝牙的体系结构及其层次,描述和定义了蓝牙的关键特性,定义了设备在协议栈的特定层上进行重要操作的方法和通信…

【圣诞限定】2022的末尾,送TA一颗圣诞树吧

2022年圣诞节,很高兴能遇见你。 一、前言 不知不觉又到年末啦,今年遇到了超级超级棒的人,希望能跟他一起做很多很多事,完成很多很多未完成的心愿。既然是圣诞节限定,那就送他一颗圣诞树吧🎄天天开心&#…

开发者百宝箱——DevToys

开发者百宝箱——DevToys 文章目录 简介安装转换类型编码/解码格式化生成器文本处理图片设置参考文献 简介 DevToys 是一个开发人员的工具箱,基于 UWP 开发,免费开源无广告,支持中文,功能有: 转换类型 JSON / YAML…

【C语言进阶】指针的进阶

在初级阶段的《指针》章节已经接触过了,我们知道了指针的概念: 1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。 2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。 3. 指针是有类型&#…

Word处理控件Aspose.Words功能演示:使用 C# 将 PowerPoint 演示文稿转换为 Word 文档

Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作任务。API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word。此外, Aspose API支持流行文件格式处…

Android自动化打包记录--Jenkins+Docker+WSL2

Android自动化打包记录--JenkinsDockerWSL2前言自动化流程测试环境生产环境自动化原理Windows下安装Ubuntu安装步骤相关error处理error: 0x8007019eerror: 0x800701bc、0x80370102WSL访问WindowsWSL访问内网Ubuntu下Docker内容安装运行HelloWorld拉取镜像镜像和容器命令创建镜像…

你不一定了解MySQL中的Decimal数据类型

一、前言 在此之前笔者写过一篇博客《你说精通MySQL其实很菜jī(1):你不一定会的基本技巧或知识点(值得一看)》,本文内容是从那篇博客截取出来的。MySQL中Decimal数据类型大家经常使用到,但是&a…

从零了解多线程(万字详解)

目录 为什么要引入多线程? 为什么线程更轻? 线程和进程的关系 多线程的弊端 Thread类 用Thread类创建一个线程并启动它 用一段通过多线程体现并发执行的效果 start和run的区别 使用jdl自带的工具包jconsole查看当前java进程中的所有线程 调用栈 注意: jave中创建线…

Duplicate File Finder Pro - 重复文件查找器,给你的 Mac 清理出大量磁盘空间

Duplicate File Finder Pro - 重复文件查找器,给你的 Mac 清理出大量磁盘空间 重复文件查找器 Duplicate File Finder Pro 是一个实用程序,只需3次点击就能在Mac上找到重复的文件。拖放功能和尽可能多的文件夹,你想,然后按下扫描按…

理解Linux中的进程状态

文章目录运行状态阻塞状态挂起状态磁盘睡眠状态暂停状态追踪停止状态僵尸状态死亡状态孤儿状态Linux内核进程状态源代码一台电脑一般只有一个CPU、一个磁盘(无论一台电脑有几个CPU、磁盘,数量都是远少于进程的,这里举例用一个)。运…

2022年广西食品安全管理员模拟试题及答案

百分百题库提供食品安全管理员考试试题、食品安全管理员考试预测题、食品安全管理员考试真题、食品安全管理员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 一、单选题 1.(重点)《上海市集体用餐配…

深度对比MemcacheD 和 Redis,论你不知道的二三事

谈到深度对比MemcacheD 和 Redis,作为老牌程序员首先想到的就是Memcache好一点,毕竟更节省内存。还可以存图片视频之类的,大部分市面上的cache都是MemcacheD。 但是评价一款cache并不能只看这一方面不是~ 数据存储的安全系数 要知道&#…

2023春招面试题:Redis数据库面试题整理

redis是什么?(必会) Redis 是 C 语言开发的一个开源的(遵从 BSD 协议)高性能非关系型(NoSQL)的(key-value)键值对数据库。可以用作数据库、缓存、消息中间件等。 redis…

STM32F103学习

目录 1、框架了解 2.GPIO (1)开漏输出与推挽输出 (2)基本知识了解 HAL库函数: 配置流程: (3)按键实验:STM32的按键开发基础_哔哩哔哩_bilibili 3、时钟 时钟框图…

力扣(leetcode)经典题目分享第3期——栈和队列

栈和队列一. 选择题1.1 进出栈顺序1.2 循环队列1.3 队列的基本运算1.4 循环队列的有效长度二. OJ练习题2.1 括号匹配问题2.2 用队列实现栈2.3 用栈实现队列2.4 循环队列总结:一. 选择题 1.1 进出栈顺序 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈&…

unreal编译源码搭建dedicated server的流水账——但是细

参考视频: B站的视频: https://www.bilibili.com/video/BV1wk4y1m7wz/?spm_id_from333.337.search-card.all.click&vd_sourced33b44674c517c8b7928e8d3ac316b37 YouTube的视频: https://www.youtube.com/watch?vAKiGajA7AXM 和上面的视…

基于STM32CUBEMX驱动多个VL6180X

概述 VL6180X是基于ST FlightSense™专利技术的最新产品。这是一个突破性的技术,实现了独立于目标反射率的绝对距离测量。现有技术通过测量反射光的光量来估算距离,这种方法的最大缺点是被测物体的颜色和表面对测量精度影响很大,而VL6180X则…

云端办公后,协同软件也能轻松做好项目管理

最近很多朋友在后台问我,数字化移动办公环境下如何做好项目管理,但是问题不够聚焦,所以我决定从自己的理解出发,分享一下项目管理的一些心得。需要说明的是,传统项目管理和互联网项目管理存在很大的差异,尤…

MyBatis源码(二)如何执行sql

前言 接着environmentElement获取数据源信息后,同级执行代码的mappersElement。 Mybatis源码(三)如何操作数据库 MyBatis源码(二)如何执行sql Mybatis源码(一)获取数据源 结构小结 分析ma…