(indexbyte1<<8)|indexbyte2——得到index
1,从runtimeconstantpool中取得index处的FieldRef,FieldRef已经解析完成
FieldRef fieldRef = (FieldRef) runtimeConstantPool.getConstant(index);
2,获取FieldRef所知识的字段和字段所在的类
field = fieldRef.getResolvedFieldRef();
JClass targetClazz = field.getClazz();
3,检查字段B所属的类是否已被初始化,如果没有,就初始化
if (targetClazz.getInitState() == InitState.PREPARED) { frame.setNextPC(frame.getNextPC() - 3);//opcode + operand = 3bytes targetClazz.initClass(frame.getThread(), targetClazz); return; }
4,如果Field是不是静态字段,抛出IncompatibleClassChangeError()
if (!field.isStatic()) { throw new IncompatibleClassChangeError(); }
5,getstatic的目的——取出字段的值,放入操作数栈中
静态字段——就是静态变量,静态字段的值就是静态变量的值
我们在加载——链接过程中,把除了非静态字段以外的全部信息都放在JClass对象上,然后把JClass对象添加到方法区中
其中静态字段——非final,把字段对应的默认值,放入JClass对象的 Vars staticVars中的staticVars[slotID]中;
final,从运行时常量池中取出字段的值,放入JClass对象的 Vars staticVars中的staticVars[slotID]中
所以我们现在要取出字段的值——从字段所属的JClass对象的staticVars中根据字段的ID取出字段的值
String descriptor = field.getDescriptor(); int slotID = field.getSlotID(); Vars staticVars = targetClazz.getStaticVars(); OperandStack stack = frame.getOperandStack(); switch (descriptor.charAt(0)) { case 'Z': case 'B': case 'C': case 'S': case 'I': stack.pushInt(staticVars.getInt(slotID)); break; case 'F': stack.pushFloat(staticVars.getFloat(slotID)); break; case 'J': stack.pushLong(staticVars.getLong(slotID)); break; case 'D': stack.pushDouble(staticVars.getDouble(slotID)); break; case 'L': case '[': stack.pushObjectRef(staticVars.getObjectRef(slotID)); break; default: