这里写自定义目录标题
写在前面
由于了好久终于想好动手完成这个项目,对我来说无疑是一个大的挑战,最开始学习共语言的目的是go越来越火想用这个技能来获得一份不错的收入,当我用工作之余完成go的基础学习后,迫不及待地的用go完成了几个小项目,最终我发现go和java还是有较大差距的,从生态上来说用java的小伙伴无疑是最开心的,几乎任何问题都能百度到一两点用来参考,而go就悲剧了,同样用java开发一个web项目那叫一个快,用go的话你可能会遇到百度都百度不到的问题,就excel的解析用go的第三方包bug满天飞不如自己写一个呢,用java几乎用不到自己来写某个东西,都是现成的,就go最擅长的并发和网络编程,我尝试了后对比netty,感觉go不是那么香了,但是我缺一门造轮子和写桌面应用的语言,不选择c++是因为go感觉还是会大火
用go写jvm的目的
本着继续加强go的语法,突破java的瓶颈,选择这个方式来完成,再有就是jvm的内存管理我不想写,go有类似java的内存管理机制自动回收,所以选择这个方案。
初识class文件
class文件是什么?反正就是java编译后的东西,此后系列文章都用我自己的语言解释,有错误的地方可以评论区指出来,毕竟我的水平有限,另外就是我会以我的视角来写,不官方的描述解释一些东西。
现在我们来写一个类
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
编译一下,或者在idea里面运行一下找到对应的class文件
现在想办法看看class文件的内容,在这里要提示各位,我们程序员从来都是byte加16进制,没有其它的,尤其是网络编程物联网等没有字符串就是byte和16进制
写一段程序读取class文件的内容
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.ReadFile("main.class")
if err != nil {
panic(err)
}
for _, o := range file {
sprintf := fmt.Sprintf("%02X ", o)
fmt.Print(sprintf)
fmt.Print(" ")
}
}
运行结果
CA FE BA BE 00 00 00 34 00 22 0A 00 06 00 14 09 00 15 00 16 08 00 17 0A 00 18 00 19 07 00 1A 07 00 1B 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00 04 74 68 69 73 01 00 06 4C 4D 61 69 6E 3B 01 00 04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 4D 61 69 6E 2E 6A 61 76 61 0C 00 07 00 08 07 00 1C 0C 00 1D 00 1E 01 00 0C 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 07 00 1F 0C 00 20 00 21 01 00 04 4D 61 69 6E 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D