美文网首页
17、ClassLoader原理

17、ClassLoader原理

作者: 陈桐Caliburn | 来源:发表于2020-05-23 18:49 被阅读0次

gojvm目录
1、搭建go环境
2、cmd命令行参数解析
3、搜索class文件
4、添加testOption 便于单元测试
5、解析classfile文件
6、运行时数据区
7、指令集
8、解释器
9、创建Class
10、类加载器
11、对象实例化new object
12、方法调用和返回
13 类初始化
14、jvm支持数组
15、jvm支持字符串-数组扩展
16、本地方法调用
17、ClassLoader原理
18、异常处理
19、 启动jvm

ClassLoader原理

class 与 object互相引用,可以让class找到实例,实例找到对应class

type Class struct {
    jClass            *Object       // java.lang.Class实例
}

// 表示实例
type Object struct {
    extra interface{}  //todo native 记录额外信息 class
}

classLoader原理

  • 1 、先加载"java/lang/Class"
  • 2、加载基本数据类型
// 创建一个类加载器
//todo bootstrp ClassLoader启动类加载器   
func NewClassLoader(cp *classpath.Classpath, verboseFlag bool) *ClassLoader {
    loader := &ClassLoader{
        cp:          cp,
        verboseFlag: verboseFlag, //添加测试标志
        classMap:    make(map[string]*Class),
    }

    //先载入java.lang.Class
    loader.loadBasicClasses()
    //加载基本类型
    loader.loadPrimitiveClasses()

    return loader
}

先加载class ,构建class与object关系

func (self *ClassLoader) loadBasicClasses() {

    //bootstrap loader 先加载 java/lang/Class
    jlClass := self.LoadClass("java/lang/Class")
    //互相引用 class与object ,便于互相查找
    for _, class := range self.classMap {
        if class.jClass == nil {
            class.jClass = jlClass.NewObject() //新建object
            class.jClass.extra = class         // object.extra 指向当前class
        }
    }

}

加载基本数据类型

//加载基本类型
func (self *ClassLoader) loadPrimitiveClasses() {
    for primitiveType, _ := range primitiveTypes {
        self.loadPrimitiveClass(primitiveType)
    }
}

// void
func (self *ClassLoader) loadPrimitiveClass(className string) {

    class := &Class{
        accessFlags: ACC_PUBLIC,
        name:        className,
        loader:      self,
        initStarted: true,
    }

    class.jClass = self.classMap["java/lang/Class"].NewObject()
    class.jClass.extra = class
    self.classMap[className] = class
}

LoadClass

// 把类数据加载到方法区
func (self *ClassLoader) LoadClass(name string) *Class {
    if class, ok := self.classMap[name]; ok {
        return class // 类已经加载
    }

    var class *Class

    //数组类型
    if name[0] == '[' {
        class = self.loadArrayClass(name)
    } else {
        class = self.loadNonArrayClass(name)
    }

    //互相引用 class与object
    if jlClass, ok := self.classMap["java/lang/Class"]; ok {
        class.jClass = jlClass.NewObject()
        class.jClass.extra = class
    }

    return class // 普通类的数据来自于class文件,数组类的数据是jvm在运行期间动态生成的
}

native/java/lang/Class.go

const jlClass = "java/lang/Class"

func init() {
    native.Register(jlClass, "getPrimitiveClass", "(Ljava/lang/String;)Ljava/lang/Class;", getPrimitiveClass)
    native.Register(jlClass, "getName0", "()Ljava/lang/String;", getName0)
    native.Register(jlClass, "desiredAssertionStatus0", "(Ljava/lang/Class;)Z", desiredAssertionStatus0)
    native.Register(jlClass, "isInterface", "()Z", isInterface)
    native.Register(jlClass, "isPrimitive", "()Z", isPrimitive)
}

// static native Class<?> getPrimitiveClass(String name);
// (Ljava/lang/String;)Ljava/lang/Class;
func getPrimitiveClass(frame *rtda.Frame) {
    nameObj := frame.LocalVars().GetRef(0)
    name := heap.GoString(nameObj)

    loader := frame.Method().Class().Loader()
    class := loader.LoadClass(name).JClass()

    frame.OperandStack().PushRef(class)
}

// private native String getName0();
// ()Ljava/lang/String;
func getName0(frame *rtda.Frame) {
    this := frame.LocalVars().GetThis()
    class := this.Extra().(*heap.Class)

    name := class.JavaName()
    nameObj := heap.JString(class.Loader(), name)

    frame.OperandStack().PushRef(nameObj)
}

// private static native boolean desiredAssertionStatus0(Class<?> clazz);
// (Ljava/lang/Class;)Z
func desiredAssertionStatus0(frame *rtda.Frame) {
    // todo
    frame.OperandStack().PushBoolean(false)
}

// public native boolean isInterface();
// ()Z
func isInterface(frame *rtda.Frame) {
    vars := frame.LocalVars()
    this := vars.GetThis()
    class := this.Extra().(*heap.Class)

    stack := frame.OperandStack()
    stack.PushBoolean(class.IsInterface())
}

// public native boolean isPrimitive();
// ()Z
func isPrimitive(frame *rtda.Frame) {
    vars := frame.LocalVars()
    this := vars.GetThis()
    class := this.Extra().(*heap.Class)

    stack := frame.OperandStack()
    stack.PushBoolean(class.IsPrimitive())
}

class文件加载顺序

+ go run main -verbose:class -cp test/lib/example.jar jvmgo.book.ch09.TestLoadClass
[loadNonArrayClass Loaded java/lang/Object from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded java/io/Serializable from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded java/lang/reflect/AnnotatedElement from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded java/lang/reflect/GenericDeclaration from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded java/lang/reflect/Type from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded java/lang/Class from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded jvmgo/book/ch09/TestLoadClass from /Users/chentong/github/jvmgo/go/test/lib/example.jar]
[loadNonArrayClass Loaded java/lang/Comparable from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded java/lang/CharSequence from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded java/lang/String from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[loadNonArrayClass Loaded java/lang/Cloneable from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
+ echo OK
OK

实战项目地址

https://github.com/yinlingchaoliu/jvmgo.git

提交标签 "native"

相关文章

  • 17、ClassLoader原理

    gojvm目录1、搭建go环境2、cmd命令行参数解析3、搜索class文件4、添加testOption 便于单元...

  • SpringBoot热部署使用

    devtools的原理 深层原理是使用了两个ClassLoader,一个Classloader加载那些不会改变的类...

  • Hook机制学习(四) -插件加载机制

    weishu_博客 一:Classloader加载的基本原理 基本原理:系统通过ClassLoader加载了需要的...

  • ClassLoader原理

    什么是ClassLoader java的源代码通过javac编译后,生成字节码(.class文件),通过jvm解析...

  • ClassLoader原理

    一. 什么是ClassLoader? 大家都知道,编译完后的java项目是由若干个.class文件组织而成的,当程...

  • 热修复原理与基础范例

    原理 ClassLoader 与 双亲委托 热修复建立的基础是 ClassLoader 的加载机制。 Androi...

  • 初识ClassLoader

    ClassLoader原理 ClassLoader使用双亲委托模型来对类进行搜索加载。除了最基础的BootStra...

  • Android插件化原理(Small)

    插件化原理(small) ClassLoader DexClassLoader 和 PathClassLoader...

  • Android进阶解密⑤—热修复

    在此之前已经总结过ClassLoader的原理,以及通过ClassLoader方式实现的热修复思路,实现热修复的方...

  • Java ClassLoader原理

    ClassLoader概念 ClassLoader是用来动态加载class文件到内存中的机制,程序在启动时,并不会...

网友评论

      本文标题:17、ClassLoader原理

      本文链接:https://www.haomeiwen.com/subject/oksqahtx.html