jvm造轮子
博客内容来源于 刘欣老师的课程,刘欣老师的公众号 码农翻身
博客内容来源于 Java虚拟机规范(JavaSE7)
博客内容的源码 https://gitee.com/zumengjie/litejvm
阅读此博客请配合源码食用。
ClassLoader
ClassLoader就是根据类名去classpath路径上找到Class文件然后解析Class文件形成Class类对象。
package com.datang.litejvm.loader; import com.datang.litejvm.clz.Class; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import java.io.*; import java.util.ArrayList; import java.util.List; /** * @author: 顶风少年 * @Description: 类加载器 * @date: 13:54 2022/6/10 **/ public class ClassLoader { /** * @author: 顶风少年 * @Description: 存放环境变量 * @date: 21:58 2022/6/8 **/ private List<String> clzPaths = new ArrayList<String>(); /** * @author: 顶风少年 * @Description: 添加环境变量 classPath * @date: 21:53 2022/6/8 **/ public void addClassPath(String path) { if (this.clzPaths.contains(path)) { return; } this.clzPaths.add(path); } /** * @author: 顶风少年 * @Description: 返回classPath, 多个中间使用 ; 拼接 * @date: 21:53 2022/6/8 **/ public String getClassPath() { return StringUtils.join(this.clzPaths, ";"); } /** * @author: 顶风少年 * @Description: 将classpath和className拼接获取类路径 * @date: 21:53 2022/6/8 **/ public byte[] readBinaryCode(String className) { className = className.replace(".", File.separatorChar) + ".class"; for (String path : this.clzPaths) { String clzFileName = path + File.separatorChar + className; byte[] codes = loadClassFile(clzFileName); if (codes != null) { return codes; } } return null; } /** * @author: 顶风少年 * @Description: 根据类路径读取class文件 * @date: 21:54 2022/6/8 **/ private byte[] loadClassFile(String clzFileName) { File f = new File(clzFileName); try { return IOUtils.toByteArray(new FileInputStream(f)); } catch (IOException e) { e.printStackTrace(); return null; } } /** * @author: 顶风少年 * @Description: 解析class文件形成Class对象,在这里是形成ClassFile对象 * @date: 13:55 2022/6/10 **/ public Class loadClass(String className) { byte[] codes = this.readBinaryCode(className); ClassParser parser = new ClassParser(); return parser.parse(codes); } }