1、字节码指令
Java虚拟机的指令长度为一个字节。指令用法一般是后面跟零个到多个操作参数。一个字节八位,所以指令的种类不超过256个。
常见的指令如:
加载和存储指令:iload、istore
算术指令:iadd、isub
类型转换指令:i2l、i2f
对象创建指令:new、newarray、anewarray
访问字段:getfield、putfield、getstatic、putstatic
控制转移指令:ifeq、tableswitch
方法调用指令:invokevirtual、invokeinterface、invokespecial、invokestatic、invokedynamic
抛出异常:athrow
同步:monitorenter、monitorexit。
synchronized的内部实现就是上边两个同步指令。通过javap反编译就可以看出来。通过设置class文件目标区域的特定字段标识位来实现同步。
2、编译
Java的编译器就是将源码编译成字节码结构。
但是虚拟机有一些优化,比如即时编译器(Just-In-Time/JIT code generator)就是一种在class文件中的代码被Java虚拟机加载后,生成平台相关的特定指令的编译器。
Java虚拟机是基于栈架构设计的。也就是虚拟的操作会默认从当前帧的操作数栈取操作数,并将结果压入操作数栈中。没调用一个方法,都会创建一个新的栈帧。但只有当前栈帧的操作数才是活动的。
3、class文件
每一个class文件都对应着唯一一个类或者接口的定义信息,但是类或接口不一定必须定义在文件里,比如可以通过类加载器直接生成。
class文件结构大致包括:版本信息、常量池、类信息、接口信息、字段信息、方法信息、属性信息等。
比如方法信息上包括ACCC_SYNCHRONIZED字段就是标识方法是否是同步执行的。
方法的代码在code属性中。
signature属性记录类中所有包含类型变量或参数化类型,此属性会记录泛型签名信息。
Java的一些字段和方法的规则限制就是由描述结构决定的。比如每个类的字段最多65535个,这个由classFile结构的fields_count项决定。
类或接口方法最多65535个,由classFile结构的methods_count项决定
方法参数最多255个,由方法描述符号所限制。