博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DVM 初始化 —— 关于Java类的基础知识
阅读量:7176 次
发布时间:2019-06-29

本文共 9605 字,大约阅读时间需要 32 分钟。

hot3.png

        DVM,也就是Dalvik,Android4.4之后,还推出了ART,但没有作为默认虚拟机使用,直到5.0才正式作为默认虚拟机使用。可见,一个好的东西是需要经历一些磨难才能出的来的。

        我把Java中的类分成两种:Primitive Type和Class Type,其中,Primitive Type,即我们所说的int、double等,而Class Type,即我们所说的class。而不管是何种Type,它们在虚拟机的实现中,都有自己的Class。Class是一个特殊的类,它不能被用来构造一个对象,只在虚拟机初始化的时候,唯一一次被直接加载。

      Java中的每一个类都对应着一个C++的ClassObject,包括了我们所用的int等java原始类型。一个Java类的加载,就是填充这个结构体ClassObject。

        虚拟机第一个加载的java类就是Class,以下就是虚拟机没有通过findClass去加载一个类,而是通过直接填充一个ClassObject来定义Class这个类

/*     * 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出来的

/* * 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编程中,人们又叫它“签名”。

/* (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里面定义。

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()方法初始化的。

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的填充。

转载于:https://my.oschina.net/u/217380/blog/321188

你可能感兴趣的文章
Java 之继承和 final 关键字
查看>>
Spring 框架的事务管理
查看>>
Number Sequence
查看>>
Unicode
查看>>
手工命令行打包java工程为war包
查看>>
待研究的技术第二版
查看>>
Python生成器及send用法讲解
查看>>
MySQL集群架构:MHA+MySQL-PROXY+LVS实现MySQL集群架构高可用/高性能-技术流ken
查看>>
eclipse导出maven依赖的jar包
查看>>
bi平台是如何进行数据的采集呢
查看>>
css3实现手机qq空间菜单按钮
查看>>
A Tour of Go Methods with pointer receivers
查看>>
持续集成工具hudson【转载】
查看>>
UC浏览器 分享到朋友圈和微信好友
查看>>
WPF入门教程系列二——Application介绍
查看>>
【17】迭代器模式(Iterator Pattern)
查看>>
linux下export命令添加、删除环境变量(转载)
查看>>
ListView优化
查看>>
【Java例题】5.3 线性表的使用
查看>>
http中的post与get
查看>>