在上几篇中留下了一个疑点
struct DataObject {
Object obj; /* MUST be first item */
/* variable #of u4 slots; u8 uses 2 slots */
u4 instanceData[1];
};
这个数据类型是怎样使用的,其中 instanceData 又是表达怎样的信息。只能打开源码,继续深入了。
经过不断的探索,找到如下一些代码:
DataObject* dvmWrapPrimitive(JValue value, ClassObject* returnType)
{
static const char* boxTypes[] = { // order from enum PrimitiveType
"Ljava/lang/Boolean;",
"Ljava/lang/Character;",
"Ljava/lang/Float;",
"Ljava/lang/Double;",
"Ljava/lang/Byte;",
"Ljava/lang/Short;",
"Ljava/lang/Integer;",
"Ljava/lang/Long;"
};
ClassObject* wrapperClass;
DataObject* wrapperObj;
s4* dataPtr;
PrimitiveType typeIndex = returnType->primitiveType;
const char* classDescriptor;
if (typeIndex == PRIM_NOT) {
/* add to tracking table so return value is always in table */
if (value.l != NULL)
dvmAddTrackedAlloc(value.l, NULL);
return (DataObject*) value.l;
}
assert(typeIndex >= 0 && typeIndex < PRIM_MAX);
if (typeIndex == PRIM_VOID)
return NULL;
classDescriptor = boxTypes[typeIndex];
wrapperClass = dvmFindSystemClass(classDescriptor);
if (wrapperClass == NULL) {
LOGW("Unable to find '%s'\n", classDescriptor);
assert(dvmCheckException(dvmThreadSelf()));
return NULL;
}
wrapperObj = (DataObject*) dvmAllocObject(wrapperClass, ALLOC_DEFAULT);
if (wrapperObj == NULL)
return NULL;
dataPtr = (s4*) wrapperObj->instanceData;
/* assumes value is stored in first instance field */
/* (see dvmValidateBoxClasses) */
if (typeIndex == PRIM_LONG || typeIndex == PRIM_DOUBLE)
*(s8*)dataPtr = value.j;
else
*dataPtr = value.i;
return wrapperObj;
}
JValue 是一个联合体,可以表示很多种数据,这个方法就是把这个数据生成一个数据对像。
我们看 boxTypes 中就能看到,这个数据结构体能表达的类型是哪些了,和我们猜测的基本相同, Boolean、Character、Float、Double、Byte、Short、Integer、Long
通过 dvmAllocObject 生成一个对像,再取出 instanceData 数据指针,根据类型是否为 PRIM_LONG 或 PRIM_DOUBLE 赋值 value.j 或 value.i
同时我们也能看出在 ClassObject 中有一个变量 primitiveType 是对一个类对像的类型进行智能判断的最有效的依据。
而 instanceData 确实是存储了一些原始类型的数据信息!