测试
周志明老师的《深入理解java虚拟机》
字节码指令构成
学类文件结构的时候,在方法表的属性表的 Code
属性表中的 code
属性中,我们知道 code
属性就是保存方法编译以后的字节码指令的。其中 code
属性是 u1
类型的,占用一个字节,这一个字节表达的数字叫做 操作码。每个操作码后面跟随的零个或多个参数,称为 操作数 。字节码指令由它们构成。
字节码指令 = 操作数 + 操作码 ;
其中 java
虚拟机采用面向操作数栈的架构,因此,大部分指令都只有一个操作码,没有参数部分的操作数。这里仅需要知道 java
采用的是基于操作数栈的架构即可,理由在书的第八章会讲。
字节码指令集的特点
没看懂(Class
文件放弃了编译后代码的操作数长度对齐 这句话。。。。)
字节码与数据类型
大部分的指令,都包含了操作对应的数据类型信息。
比如 iload
,表示从局部变量表中加载 int
类型的数据到操作数栈中。而 fload
则表示从局部变量表中加载 float
类型的数据到操作数栈中。在 Class
文件中,这两种操作对用两条不一样的指令,但是在 JVM
内部实现的时候,这两条指令可以由同一段代码完成。
其中与数据类型有关的指令,它的操作码中都有特殊的助记符表明操作哪种数据类型,如 i
代表 int
,f
代表 float
等。
助记符 | 操作的类型 |
---|---|
b |
byte |
c |
char |
s |
short |
i |
int |
f |
float |
d |
double |
l |
long |
a |
reference |
只有最后的 引用类型 reference
是 a
需要记下,其他的都是类型的第一个字母。
还有一些与数据类型无关的操作码 arraylength
,它操作的就是 数组 。
class cglibProxy implements MethodInterceptor {
/**
* @param o 生成的代理类
* @param method 调用的方法
* @param objects 参数
* @param methodProxy 方法代理
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println(o.getClass().getName());
System.out.println(methodProxy.getClass().getName());
Object result = methodProxy.invokeSuper(o, objects);
return result;
}
}