关于Java类加载器的一些理解
Java中,每个类都可以获得对应自己类的Class对象,这是因为Object类中有public final native getClass()方法,Class对象是由类加载器根据类字节码生成的,是反射机制必不可少的部分。
类加载器中,主要的方法有protected Class loadClass(String name, boolean resolve)和protected Class findClass(String name)两个方法。
loadClass方法用来实现双亲委派机制,resolve
参数用于指示是否在加载类之后立即进行解析(resolve)操作,解析是指将类的符号引用解析为直接引用,以确保类的正确链接和初始化:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { //首先,检查该类是否已经加载过 Class c = findLoadedClass(name); if (c == null) { //如果 c 为 null,则说明该类没有被加载过 long t0 = System.nanoTime(); try { if (parent != null) { //当父类的加载器不为空,则通过父类的loadClass来加载该类 c = parent.loadClass(name, false); } else { //当父类的加载器为空,则调用启动类加载器来加载该类 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { //非空父类的类加载器无法找到相应的类,则抛出异常 } if (c == null) { //当父类加载器无法加载时,则调用findClass方法来加载该类 //用户可通过覆写该方法,来自定义类加载器 long t1 = System.nanoTime(); c = findClass(name); //用于统计类加载器相关的信息 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
findClass方法用于父加载器无法加载指定类时,子加载器本身进行加载并返回Class对象,因为ClassLoader抽象类findClass方法默认为空,接下来以AppClassLoader中的findClass方法为例:
protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] b = loadClassBytes(name);//先加载字节码 return defineClass(name, b, 0, b.length);//返回Class对象 }
接下来看一下loadClassBytes方法:
private byte[] loadClassBytes(String name) throws ClassNotFoundException { // 将类名转换为文件路径 String filePath = classNameToFilePath(name); // 读取类文件内容 byte[] classBytes = readFileBytes(filePath); // 返回类字节码数组 return classBytes; }
到此可知,一般自定义类加载器继承ClassLoader,不想改变双亲委派机制的话,只要重写findClass方法,否则,则要重写loadClass
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!