类加载过程

  1. 我们写的 .java 文件,通过 javac 编译生成 .class 字节码,JVM 能够识别并执行这些 .class 文件。Kotlin 也是如此,kotlinc 会将 .kt 文件编译成 .class,最终统一运行在 JVM 上。

  2. 在 Android 中,.class 文件会被打包进 .dex。App 启动时,系统创建 PathClassLoader,并将 .dex 的路径保存在其内部的 DexPathList 中——此时只是记录路径,类还未加载

  3. 当执行到 new 某个类时,ClassLoader 才会遍历 DexPathList,查找并加载该类。
    加载到内存” 的本质是:在 JVM 的方法区创建一个 java.lang.Class 对象,作为该类的“运行时模版”,后续通过 new 创建的实例都基于这个模版。
    如果类已加载,ClassLoader 会直接从缓存返回已有的 Class 对象,不会重复加载

  4. 反射机制,就是我们可以通过一个实例(比如 user),调用 getClass(),反向拿到它的 Class 模版。
    就像:

    • 正常是“根据设计图建房子”(new User()
    • 反射是“通过房子反推设计图”,甚至可以修改设计图(如访问私有字段、调用私有方法),从而动态控制对象行为。
  5. 双亲委派机制,是为了防止我们篡改系统类。
    比如你写了一个 java.lang.StringPathClassLoader 想加载它,但必须先委托 BootClassLoader
    而系统类早已被 BootClassLoader 加载并缓存,它会直接返回真正的 String,你的恶意类根本无法加载——系统核心类因此得到保护

  6. 实际的加载顺序是:
    子加载器缓存 → 父加载器缓存 → 父加载器尝试加载 → 父加载失败 → 子加载器加载
    具体到 Android:
    PathClassLoader 先查自己缓存 → 委托 BootClassLoaderBootClassLoader 查自己缓存 → 尝试加载(失败)→ 回退到 PathClassLoader 自己加载。

  7. 热修复就是,修改设计图纸:通过反射机制,修改pathList,替换掉原来的class,这样要加载的时候,就会使用心得class
posted @ 2025-08-26 11:28  蜗牛攀爬  阅读(8)  评论(0)    收藏  举报