(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: