当前位置: 首页 > news >正文

Java的类加载机制和类对象

在使用Java 语言开发时,Class Loader可能是一个不用关注的概念,但是在某些疑难问题的解决的时候,可能需要掌握相关的知识,比如笔者在这一篇遇到的问题: Spring Boot JPA 开发之Not an entity血案。 接下来就来全面的看一看Java的类加载机制。

一、类加载器(Class Loader)

类加载器是JVM的一部分,负责将类的字节码文件(.class)动态加载到内存中,并生成对应的java.lang.Class对象。Java采用分层类加载模型,主要有以下三类加载器:

  1. Bootstrap ClassLoader(启动类加载器)
    • 职责:加载JVM核心类库(如java.lang.*),路径为<JAVA_HOME>/jre/lib
    • 实现:由C/C++编写,是JVM的一部分,无Java类实例。
    • 特性:唯一没有父加载器的类加载器。
  2. Extension ClassLoader(扩展类加载器)
    • 职责:加载扩展目录(<JAVA_HOME>/jre/lib/ext)中的类。
    • 实现:由sun.misc.Launcher$ExtClassLoader实现,父加载器为Bootstrap。
  3. Application ClassLoader(应用程序类加载器)
    • 职责:加载用户类路径(-classpathCLASSPATH环境变量)的类。
    • 实现:由sun.misc.Launcher$AppClassLoader实现,父加载器为Extension。
  4. 自定义类加载器
    • 场景:需隔离加载(如热部署)、动态加载网络资源等。
    • 实现:继承ClassLoader,重写findClass()方法。

二、类加载机制

类加载过程分为加载、链接(验证、准备、解析)、初始化三个阶段:

  1. 加载(Loading)
    • 操作:查找字节码文件,读取到内存,生成Class对象。
    • 触发条件:首次使用类时(如new、调用静态方法等)。
  2. 链接(Linking)
    • 验证(Verification):检查字节码合法性(格式、语义、安全性)。
    • 准备(Preparation):为静态变量分配内存并赋默认值(如int初始化为0)。
    • 解析(Resolution):将符号引用(类、方法名)转为直接引用(内存地址)。
  3. 初始化(Initialization)
    • 操作:执行静态变量赋值和静态代码块(按代码顺序执行)。
    • 线程安全:JVM保证初始化过程同步。

三、双亲委派模型(Parent Delegation Model)
  1. 机制
    • 类加载器在加载类时,先将请求委派给父加载器。
    • 若父加载器无法完成(在自己的搜索范围内找不到类),子加载器才尝试加载。
  2. 优点
    • 安全性:防止核心类被篡改(如用户自定义java.lang.String无效)。
    • 避免重复:确保类全局唯一性(同一类由同一加载器加载)。
  3. 打破双亲委派
    • 场景:OSGi模块化、Tomcat隔离Web应用。
    • 方法:重写loadClass()逻辑(如优先自行加载)。

四、类对象(Class Object)
  1. 概念
    • 每个类加载后,JVM为其生成一个Class对象,存储类的元数据(方法、字段、构造器等)。
    • 是反射(java.lang.reflect)操作的基础。
  2. 获取方式
    • 类名.class(如String.class)。
    • 对象.getClass()(如new String().getClass())。
    • Class.forName("全限定类名")(动态加载,如Class.forName("java.util.ArrayList"))。
  3. 应用
    • 反射:通过Class对象实例化对象、调用方法、访问字段。
    • 动态代理:基于接口和Class对象生成代理类。

五、关键代码示例
// 自定义类加载器
public class CustomClassLoader extends ClassLoader {@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {byte[] classData = loadClassData(name); // 从自定义路径读取字节码return defineClass(name, classData, 0, classData.length);}
}// 使用Class对象反射创建实例
Class<?> clazz = Class.forName("com.example.MyClass");
Object obj = clazz.newInstance();
Method method = clazz.getMethod("myMethod");
method.invoke(obj);

六、常见问题
  1. 不同类加载器加载的类是否相同?
    • :即使全限定名相同,不同加载器加载的类在JVM中视为不同类,导致instanceof和类型转换失败。
  2. 何时触发类初始化?
    • new、静态方法调用、静态字段访问(非final)、反射调用Class.forName()(默认初始化)、子类初始化触发父类初始化等。
  3. 如何实现热部署?
    • 自定义类加载器,每次重新加载类生成新Class对象,需注意旧实例与新类不兼容。

相关文章:

  • HTML5好看的水果蔬菜在线商城网站源码系列模板4
  • Spring Boot 自定义定时任务组件深度解析:Quartz 集成与设计模式实战
  • 设计模式之工厂模式(factory pattern):在商品对象创建系统中的应用
  • 全面解析Flutter中的Stream用法及实际应用
  • 07-云原生安全深度剖析:从 Kubernetes 集群防护到微服务安全加固
  • flutter下载SDK环境配置步骤详解
  • wx219基于ssm+vue+uniapp的教师管理系统小程序
  • 模运算的基本性质
  • 重新定义“边缘”:边缘计算如何重塑人类与数据的关系
  • 记一次内存泄漏
  • 如何在 .NET 环境中使用 Npgsql 驱动连接 KaiwuDB
  • 深入探究 TCP 与 UDP 协议:原理、特性及应用
  • java CountDownLatch用法简介
  • 华为纯血 卓易通 使用记录
  • 【JavaEE初阶】多线程重点知识以及常考的面试题-多线程进阶(二)
  • Yakit的免配置浏览器不是内置浏览器
  • 【MySQL】前缀索引、索引下推、访问方法,自适应哈希索引
  • API平台(API网关)的API安全保障机制
  • 在云服务器的 Linux 系统中安装 Python 的步骤(以常见发行版 Ubuntu/CentOS 为例)
  • Linux的应用领域,Linux的介绍,VirtualBox和Ubuntu的安装,VMware的安装和打开虚拟机CentOS
  • 百度网站怎么做视频/网络推广专员岗位职责
  • 网站备案幕布怎么申请/广告软文案例
  • 怎样弄一个网站/wp博客seo插件
  • 武汉专业做网站的公司/培训机构哪家好
  • 展厅设计策划/seo综合检测
  • 广西北海疫情最新消息/seo关键词教程