DVM,也就是Dalvik,Android4.4以後,還推出了ART,但沒有做爲默認虛擬機使用,直到5.0才正式做爲默認虛擬機使用。可見,一個好的東西是須要經歷一些磨難才能出的來的。java
我把Java中的類分紅兩種:Primitive Type和Class Type,其中,Primitive Type,即咱們所說的int、double等,而Class Type,即咱們所說的class。而無論是何種Type,它們在虛擬機的實現中,都有本身的Class。Class是一個特殊的類,它不能被用來構造一個對象,只在虛擬機初始化的時候,惟一一次被直接加載。apache
Java中的每個類都對應着一個C++的ClassObject,包括了咱們所用的int等java原始類型。一個Java類的加載,就是填充這個結構體ClassObject。編程
虛擬機第一個加載的java類就是Class,如下就是虛擬機沒有經過findClass去加載一個類,而是經過直接填充一個ClassObject來定義Class這個類less
/* * Initialize the class Class. This has to be done specially, particularly * because it is an instance of itself. */ ClassObject* clazz = (ClassObject*) dvmMalloc(classObjectSize(CLASS_SFIELD_SLOTS), ALLOC_NON_MOVING); if (clazz == NULL) { return false; } DVM_OBJECT_INIT(clazz, clazz); SET_CLASS_FLAG(clazz, ACC_PUBLIC | ACC_FINAL | CLASS_ISCLASS); clazz->descriptor = "Ljava/lang/Class;"; gDvm.classJavaLangClass = clazz; LOGVV("Constructed the class Class.");
Primitive Type在虛擬機中是被enum出來的spa
/* * Enumeration of all the primitive types. */ enum PrimitiveType { PRIM_NOT = 0, /* value is a reference type, not a primitive type */ PRIM_VOID = 1, PRIM_BOOLEAN = 2, PRIM_BYTE = 3, PRIM_SHORT = 4, PRIM_CHAR = 5, PRIM_INT = 6, PRIM_LONG = 7, PRIM_FLOAT = 8, PRIM_DOUBLE = 9, };
Primitive Type不像class type,有一個類所在的路徑,它是被規定死了一些對應字母,在JNI編程中,人們又叫它「簽名」。
rest
/* (documented in header) */ const char* dexGetPrimitiveTypeDescriptor(PrimitiveType type) { switch (type) { case PRIM_VOID: return "V"; case PRIM_BOOLEAN: return "Z"; case PRIM_BYTE: return "B"; case PRIM_SHORT: return "S"; case PRIM_CHAR: return "C"; case PRIM_INT: return "I"; case PRIM_LONG: return "J"; case PRIM_FLOAT: return "F"; case PRIM_DOUBLE: return "D"; default: return NULL; } return NULL; }
Class Type都有一個包名+類名的形式,而在被加載時,它們都變成了如"Ljava/lang/Object」;"Ljava/lang/Object;」就是Java類的祖宗Object。如下是虛擬機在初始化時,所加載的一些基礎類,它們在Java的Libcore裏面定義。code
static struct { ClassObject** ref; const char* name; } classes[] = { /* * Note: The class Class gets special treatment during initial * VM startup, so there is no need to list it here. */ /* The corest of the core classes */ { &gDvm.classJavaLangObject, "Ljava/lang/Object;" }, { &gDvm.exThrowable, "Ljava/lang/Throwable;" }, /* Slightly less core, but still down there, classes */ { &gDvm.classJavaLangClassArray, "[Ljava/lang/Class;" }, { &gDvm.classJavaLangClassLoader, "Ljava/lang/ClassLoader;" }, { &gDvm.classJavaLangObjectArray, "[Ljava/lang/Object;"}, { &gDvm.classJavaLangStackTraceElement, "Ljava/lang/StackTraceElement;" }, { &gDvm.classJavaLangStackTraceElementArray, "[Ljava/lang/StackTraceElement;" }, { &gDvm.classJavaLangString, "Ljava/lang/String;" }, { &gDvm.classJavaLangThread, "Ljava/lang/Thread;" }, { &gDvm.classJavaLangThreadGroup, "Ljava/lang/ThreadGroup;" }, { &gDvm.classJavaLangVMThread, "Ljava/lang/VMThread;" }, /* Arrays of primitive types */ { &gDvm.classArrayBoolean, "[Z" }, { &gDvm.classArrayByte, "[B" }, { &gDvm.classArrayShort, "[S" }, { &gDvm.classArrayChar, "[C" }, { &gDvm.classArrayInt, "[I" }, { &gDvm.classArrayLong, "[J" }, { &gDvm.classArrayFloat, "[F" }, { &gDvm.classArrayDouble, "[D" }, /* Exception classes */ { &gDvm.exAbstractMethodError, "Ljava/lang/AbstractMethodError;" }, { &gDvm.exArithmeticException, "Ljava/lang/ArithmeticException;" }, { &gDvm.exArrayIndexOutOfBoundsException, "Ljava/lang/ArrayIndexOutOfBoundsException;" }, { &gDvm.exArrayStoreException, "Ljava/lang/ArrayStoreException;" }, { &gDvm.exClassCastException, "Ljava/lang/ClassCastException;" }, { &gDvm.exClassCircularityError, "Ljava/lang/ClassCircularityError;" }, { &gDvm.exClassNotFoundException, "Ljava/lang/ClassNotFoundException;" }, { &gDvm.exClassFormatError, "Ljava/lang/ClassFormatError;" }, { &gDvm.exError, "Ljava/lang/Error;" }, { &gDvm.exExceptionInInitializerError, "Ljava/lang/ExceptionInInitializerError;" }, { &gDvm.exFileNotFoundException, "Ljava/io/FileNotFoundException;" }, { &gDvm.exIOException, "Ljava/io/IOException;" }, { &gDvm.exIllegalAccessError, "Ljava/lang/IllegalAccessError;" }, { &gDvm.exIllegalAccessException, "Ljava/lang/IllegalAccessException;" }, { &gDvm.exIllegalArgumentException, "Ljava/lang/IllegalArgumentException;" }, { &gDvm.exIllegalMonitorStateException, "Ljava/lang/IllegalMonitorStateException;" }, { &gDvm.exIllegalStateException, "Ljava/lang/IllegalStateException;" }, { &gDvm.exIllegalThreadStateException, "Ljava/lang/IllegalThreadStateException;" }, { &gDvm.exIncompatibleClassChangeError, "Ljava/lang/IncompatibleClassChangeError;" }, { &gDvm.exInstantiationError, "Ljava/lang/InstantiationError;" }, { &gDvm.exInstantiationException, "Ljava/lang/InstantiationException;" }, { &gDvm.exInternalError, "Ljava/lang/InternalError;" }, { &gDvm.exInterruptedException, "Ljava/lang/InterruptedException;" }, { &gDvm.exLinkageError, "Ljava/lang/LinkageError;" }, { &gDvm.exNegativeArraySizeException, "Ljava/lang/NegativeArraySizeException;" }, { &gDvm.exNoClassDefFoundError, "Ljava/lang/NoClassDefFoundError;" }, { &gDvm.exNoSuchFieldError, "Ljava/lang/NoSuchFieldError;" }, { &gDvm.exNoSuchFieldException, "Ljava/lang/NoSuchFieldException;" }, { &gDvm.exNoSuchMethodError, "Ljava/lang/NoSuchMethodError;" }, { &gDvm.exNullPointerException, "Ljava/lang/NullPointerException;" }, { &gDvm.exOutOfMemoryError, "Ljava/lang/OutOfMemoryError;" }, { &gDvm.exRuntimeException, "Ljava/lang/RuntimeException;" }, { &gDvm.exStackOverflowError, "Ljava/lang/StackOverflowError;" }, { &gDvm.exStaleDexCacheError, "Ldalvik/system/StaleDexCacheError;" }, { &gDvm.exStringIndexOutOfBoundsException, "Ljava/lang/StringIndexOutOfBoundsException;" }, { &gDvm.exTypeNotPresentException, "Ljava/lang/TypeNotPresentException;" }, { &gDvm.exUnsatisfiedLinkError, "Ljava/lang/UnsatisfiedLinkError;" }, { &gDvm.exUnsupportedOperationException, "Ljava/lang/UnsupportedOperationException;" }, { &gDvm.exVerifyError, "Ljava/lang/VerifyError;" }, { &gDvm.exVirtualMachineError, "Ljava/lang/VirtualMachineError;" }, /* Other classes */ { &gDvm.classJavaLangAnnotationAnnotationArray, "[Ljava/lang/annotation/Annotation;" }, { &gDvm.classJavaLangAnnotationAnnotationArrayArray, "[[Ljava/lang/annotation/Annotation;" }, { &gDvm.classJavaLangReflectAccessibleObject, "Ljava/lang/reflect/AccessibleObject;" }, { &gDvm.classJavaLangReflectConstructor, "Ljava/lang/reflect/Constructor;" }, { &gDvm.classJavaLangReflectConstructorArray, "[Ljava/lang/reflect/Constructor;" }, { &gDvm.classJavaLangReflectField, "Ljava/lang/reflect/Field;" }, { &gDvm.classJavaLangReflectFieldArray, "[Ljava/lang/reflect/Field;" }, { &gDvm.classJavaLangReflectMethod, "Ljava/lang/reflect/Method;" }, { &gDvm.classJavaLangReflectMethodArray, "[Ljava/lang/reflect/Method;"}, { &gDvm.classJavaLangReflectProxy, "Ljava/lang/reflect/Proxy;" }, { &gDvm.classJavaNioReadWriteDirectByteBuffer, "Ljava/nio/ReadWriteDirectByteBuffer;" }, { &gDvm.classOrgApacheHarmonyDalvikDdmcChunk, "Lorg/apache/harmony/dalvik/ddmc/Chunk;" }, { &gDvm.classOrgApacheHarmonyDalvikDdmcDdmServer, "Lorg/apache/harmony/dalvik/ddmc/DdmServer;" }, { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory, "Lorg/apache/harmony/lang/annotation/AnnotationFactory;" }, { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember, "Lorg/apache/harmony/lang/annotation/AnnotationMember;" }, { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray, "[Lorg/apache/harmony/lang/annotation/AnnotationMember;" }, { NULL, NULL } };
上面還只是一個部分羅列,不過您也應該能看到不少熟悉又陌生的「類」了吧。DVM在初始化時,就把這些基礎類保存下來了,以便於人們能夠用來定義其餘的類。那麼加載呢?真正的加載,是經過initClassReference()方法初始化的。orm
static bool initClassReference(ClassObject** pClass, const char* name) { ClassObject* result; assert(*pClass == NULL); if (name[0] == '[') { result = dvmFindArrayClass(name, NULL); } else { result = dvmFindSystemClassNoInit(name); } if (result == NULL) { ALOGE("Could not find essential class %s", name); return false; } *pClass = result; return true; }
而initClassReference()方法又是經過dvmFindArrayClass()和dvmFindSystemClassNoInit()來加載的,這裏能夠簡單的把它們都當作findClass()。對象
findClass(),就是咱們所說的一個類的加載,也就是完成結構體ClassObject的填充。
ip