1.从0开始的手写java虚拟机 - 读取类路径下的class文件

本文详细介绍了从0开始手写Java虚拟机的过程中,如何读取类路径下的class文件,包括启动类路径、扩展类路径和用户类路径的加载顺序,以及从jar和目录加载class文件的实现。通过示例展示了如何加载java.lang.Object、com.mysql.cj.jdbc.Driver和org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration等类。
摘要由CSDN通过智能技术生成

读取类路径下的class文件

1.思路

加载class文件时,会从
启动类路径(/jre/lib),
扩展类路径(/jre/lib/ext),
用户类路径(用户当前路径),
中加载文件;
因此jvm启动时会将上述三种类型的路径读入内存中,当我们需要使用到某一具体的类文件时,就会从这些路径中加载(加载顺序为 启动类 -》扩展类 -》 用户类);
且加载文件的方式也有多种,如直接从文件夹中加载class文件,从jar中加载class文件,还有就是通配符*加载目录下全部文路劲(包括普通文件夹以及压缩包);

1.1.entry.go

可以从多个地方查找class文件,如jar,文件夹,因此面向接口编程,定义接口

package classpath

import (
	"os"
	"strings"
)

const pathListSeparator = string(os.PathListSeparator)
type Entry interface {
   
	readClass(ClassName string) ([]byte, Entry, error)
	String() string
}

func newEntry(path string) Entry 
//若 -cp或-classpath中包含由分号分割的多个类文件,则将其分割并递归调用本函数
	if strings.Contains(path, pathListSeparator) {
   
		return newCompositeEntry(path)
	}

//若-cp后的值包含*,则说明要将相应目录下的所有class文件加载
	if strings.HasSuffix(path, "*") {
   
		return newWildcardEntry(path)
	}

//若-cp后的值包含.jar,则说明是jar文件,通过zip方式加载
	if strings.HasSuffix(path, ".jar") || strings.HasSuffix(path, ".JAR") || strings.HasSuffix(path, ".zip") || strings.HasSuffix(path, ".ZIP") {
   
		return newZipEntry(path)
	}
	return newDirEntry(path)
}

1.2.entry_dir

我们可以从目录下加载class文件

package classpath

import (
	"io/ioutil"
	"path/filepath"
)

//读取目录下的class文件
type DirEntry struct {
   
	absDir string
}

func newDirEntry(path string) *DirEntry {
   
	absDir, err := filepath.Abs(path)
	if err != nil {
   
		panic(err)
	}
	return &DirEntry{
   absDir: absDir}
}

func (self *DirEntry) readClass(className string) ([]byte, Entry, error) {
   
	fileName := filepath.Join(self.absDir, className)
	data, err := ioutil.ReadFile(fileName)
	return data, self, err
}

func (self *DirEntry) String() string {
   
	return self.absDir
}


1.3.entry_zip.go

我们可以从jar包中加载class文件

package classpath

import (
	"archive/zip"
	"errors"
	"io/ioutil"
	"path/filepath"
)

//读取zip如.jar中读取class文件
type ZipEntry struct {
   
	absPath string
}

func newZipEntry(path string) *ZipEntry {
   
	absPath, err := filepath.Abs(path)
	if err != nil {
   
		panic(er
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值