1、什么是字节码文件呢?
从以上的图可以知道, 字节码文件就是由jvm处理的文件, 它符合jvm的规范.
java不同于C++, C++里面的C运行时库会因为不同系统而不同,因为需要支持不同的操作系统API.
java称为“一次编译,到处运行”, 主要是因为JVM做了一层操作系统不同API的适配, Java文件通过javac生成.class字节码文件, 相当于.class文件是一个JVM的标准, 只要按照满足这个标准的文件, JVM都能识别并且运行. 它是一个由十六进制组成的文件, JVM以字节为单位读取文件, 所以称为字节码文件.
这是网上的一个.class文件结构的说明, 里面对结构及每个占位都描述的非常详尽.
我们举一个以下的例子, 里面有一个简单的打印函数:
对该文件进行编译(javac -g Base.java)之后生成的十六进制字节码文件如下:
另外我们还可以通过javap -verbose Base.class来查看Base.class文件的结构
2、访问者模式
这是一个网上简单的一个描述图, 其实它主要就是四个角色.
- visitor抽象访问者
- concreteVisitor具体访问者, 实现visit方法
- element抽象元素, 接受visitor的访问
- concreteElement具体元素, 通常调用visitor.visit()
我的理解具体元素就是我们拥有的原始数据, 而访问者则是需要处理自己关心的数据. 举个例子, 一个班有50个学生, 每个学生都有数学, 英语, 语文三门课程. 期末考试之后, 数学老师、英语老师和语文老师需要对各自的分数进行统计, 可能每个人的统计规则是不一样的. 那么每个学生就是一个具体的元素, 抽象元素则是接受三门课老师的访问, 抽象访问者则是访问所有学生, 而每个老师则是一个具体的访问者, 每个老师都会实现自己的visit函数, 用各自的方法来统计分数.
3、ASM字节码增强技术
它属于package jdk.internal.org.objectweb.asm包内. 它是一个java字节码操作框架. 它能被用来动态生成类或者增强既有类的功能.ASM可以直接产生二进制的class文件, 也可以在类被加载入java虚拟机之前动态改变类行为.
ASM API是基于访问者模式的, 提供了ClassVisitor, MethodVisitor, FieldVisitor的API接口, 每当ASM扫描到类字段时会回调FieldVisitor的方法, 扫描到类方法时会回调MethodVisitor的方法.
ASM主要的API有以下几个:
- ClassReader: 把.class文件内容读取到内存字节数组中, 实现了accept函数.
- ClassWriter: 将修改后的类的字节码内容以字节数组的形式输出
- ClassVisitor: 访问类的各个部分. 比如访问类的头部信息, 注解, 属性, 字段, 内部类等等.
- MethodVisitor: 访问类中某个函数的各个部分. 比如访问方法的一个参数, 方法代码等等.
- FieldVisitor: 访问类中某个域的各个部分. 比如访问域的注解, 类型等.