[JVM] - 不就是JVM么 JVM的继续探究

 前面几章跟着作者的脚步实现了使用Go语言查看java的.class文件源码(16进制)

复习一下:

相比Java语言,Go的访问控制非常简单,只有公开和私有两种. 所有首字母大写的类型,

结构体,字段,变量,函数,方法等都是公开的. 可供其它包使用. 首字母小写则是私有的.

只能在包内部使用. 

接下来使用大神作者的classpy查看某个class文件,当然也能打开.jar

 这是被称呼为魔数的代码. 

很多文件格式都会规定满足该格式的文件必须以某几个固定字节开头,这几个字节主要起到标识作用, 叫做魔数( magic number )

class文件的魔术是"0xCAFEBABE"

除了Object.class, 看到OutOfMemoryError.class同样也有这个魔数

classfile/class_file.go :

func (self *ClassFile) readAndCheckMagic(reader *ClassReader) {
    magic := reader.readUint32()
    if magic != 0xCAFEBABE {
        panic("java.lang.ClassFormatError: magic!")
    }
}

通过if 判断是否为 0xCAFEBABE 继而做出响应,JAVA虚拟机规范规定,如果加载class文件不符合要求的格式,Java虚拟机实现就抛出java.lang.ClassFormatError异常

再一个是版本号.

为了还要节省时间看缓存知识,这里大概略过一下

这个是类访问标志, 作者说由于常量池比较复杂放到3.3节介绍了

常量池之后就是这个类访问标志,这是一个16位的"bitmask(位掩码)" , 指出class文件定义的是类还是接口,访问级别是public还是private,等等.

 类和超类索引, 类访问标志之后是两个u2类型的常量池索引,分别给出类名和超类名.

class文件存储的类名类似完全限定名, 但是把点换成了斜线, Java语言规范把这种名叫 二进制名 (binary names)

因为每个类都有名字,所以thisClass必须是有效的常量池索引. 

除java.lang.Object之外,

其他类都有超类, 所以superClass只在Object.class中是0 , 在其它class文件中必须是有效的常量池索引.

 <非Object.class

那么!

接口索引表 ,类和超类索引后面是接口索引表,表中存放的也是常量池索引.

给出该类实现的所有接口的名字.

拿Object.class的来看,剩下的还有这些

字段啊,方法啊,参数啊.等等吧! 忽然想起来一句话,不管之前的过往和经历如何,都是为了你能更好地成长! 所以要把失败当动力,把压力当动力!

和类一样,字段和方法也有自己的访问标志. 访问标志之后是一个常量池索引,给出字段名或方法名.

然后又是一个常量池索引,给出字段或方法的描述符,最后是属性表.

等等.

3.3节 解析常量池 (为了加快看SpringBoot底层知识,我也是加快了打字速度)

常量池呢 它占据了class文件很大一部分数据, 里面存放着各式各样的常量信息, 包括: 

数字, 字符串常量池, 类, 接口名, 字段, 方法名, 等等.

猜你喜欢

转载自www.cnblogs.com/ukzq/p/10190354.html
JVM
今日推荐