2.jvm类加载系统

编程入门 行业动态 更新时间:2024-10-27 00:25:00

2.jvm类<a href=https://www.elefans.com/category/jswz/34/1771433.html style=加载系统"/>

2.jvm类加载系统

目录

  • 概述
  • 类加载器
    • 执行顺序
    • 加载时机与过程
      • 类加载的四个时机
      • 一个类的一生
    • 类加载途径
  • 自定义类加载器
    • 工作准备
    • 编写自定义加载器
    • 结果
  • 结束

概述

类加载器

jvm 的类加载是通过 ClassLoader 及其子类来完成的。
有以下类加载器

注意: bootstrap 引导程序

根据上图总结如下

  • 启动类加载器(Bootstrap ClassLoader):负责加载 JAVA_HOME\lib 目录或通过 -Xbootclasspath 参数指定路径中的且被虚拟机认可(rt.jar) 的类库。
  • 扩展类加载器(Extension ClassLoader):负责加载 JAVA_HOME\lib\ext 目录或者通过 java.ext.dirs 系统变量指定路径中的类库。
  • 应用程序类加载器(Application ClassLoader):负责加载用户路径 classpath 上的类库 (自己编写的程序在此加载)
  • 自定义类加载器(User ClassLoader):加载应用之外的类文件 (例如:JRebel 热部署)

执行顺序

来看一下图:

  1. 检查顺序是自底向上: 加载过程中会先检查类是否被已加载,从 Custom 到 BootStrap 逐层检查,只要某个类加载器已加载就视为此类已加载,**好处:**保证此类所有 ClassLoader 只加载一次。
  2. 加载的顺序是自顶向下: 也就是由上层来逐层尝试加载此类。

加载时机与过程

类加载的四个时机

public class Student{private static int age;public static void method(){}
}// Student.age
// Student.method();
// new Student();
Class t = Class.forName("java.lang.Thread")
  • 遇到 new、getStatic、putStatic、invokeStatic 四条指令时
  • 使用 java.lang.reflect 包方法时,对类进行反射调用
  • 初始化一个类时,发现其父类还没初始化,要先初始化其父类
  • 当虚拟机启动时,用户需要指定一个主类 main,需要先将主类加载

一个类的一生

当一个 .java 文件被编译成 class 文件
类的生命周,而非对象的生命周期,看下图

类加载主要做了三件事:

  • 1.根据 类全限定名称,二进制字节流加载 class 文件
  • 2.字节流静态数据 ,进入方法区 (永久代、元空间)
  • 3.创建字节码 Class 对象

类加载途径

加载途径总结如下:

  • 1.jar/war
  • 2.jsp生成的 class
  • 3.数据库中的二进制字节流
  • 4.网络中的二进制字节流
  • 5.动态代理生成的二进制字节流

自定义类加载器

工作准备

准备好需要加载的类,代码很简单

package com.fun.demo;public class Test {public void say() {System.out.println("hello jvm");}
}

编译完成后放置如下路径: /Users/hyl/Desktop/jk/jvm/lib/com/fun/demo

编写自定义加载器

自定义类加载器 CustomClassLoader 继承 ClassLoader ;重写 findClass()方法,在findClass方法中调用 defineClass() 方法

自定义加载器如下,代码还是很简单的。

package com.fun.classloader;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class CustomClassLoader extends ClassLoader {private String rootPath;public CustomClassLoader(String rootPath) {this.rootPath = rootPath;}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {// name 传进来的全类名称String absolutePath = rootPath + "/" + name.replace(".", "/") + ".class";try {FileInputStream in = new FileInputStream(absolutePath);byte[] classByte = in.readAllBytes();return defineClass(null, classByte, 0, classByte.length);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException exception) {exception.printStackTrace();}return null;}
}

测试代码如下:

package com.fun.classloader;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;public class Test {//public static void main(String[] args) {//    String tmp = "com.fun.demo.Test";//    System.out.println(tmp.replace(".", "/"));//}public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {CustomClassLoader loader = new CustomClassLoader("/Users/hyl/Desktop/jk/jvm/lib");Class<?> clz = loader.loadClass("com.fun.demo.Test");if (Objects.nonNull(clz)) {Object o = clz.newInstance();Method method = clz.getMethod("say", null);method.invoke(o, null);}}
}

结果

运行 main 方法,得到的效果如下:

结束

至此,jvm 类加载系统就结束了,如有疑问,欢迎评论区留言。

更多推荐

2.jvm类加载系统

本文发布于:2023-11-15 03:00:59,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1592592.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:加载   系统   jvm

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!