java 类的加载

加载是将class文件加载到 jvm内存,并为之创建一个大的Class,任何类被系统使用都会建立一个大Class对象。Class用来表示文件内容,成员变量,构造方法,成员方法

连接:
         验证是否是正确的Class内部结构
         准备负责为静态成员分配内存,并设置默认初始值
         解析将类的二进制符号符号替换为直接引用(例如地址值,替换为直接指向 )
类的加载时间
         1.创建类实例时 new。
         2.为静态[变量]赋值,访问静态变量
         3.调用静态方法
         4.使用反射方法创建某个类或接口的反射方法java.lang.Class
         5.初始化某子类
         6.通过java.exe调用类的方法时
类加载器
            根类加载器
            扩展类加载器
            系统类加载

其他加载方式都是属于被动加载,不会导致类的加载和初始化 例如: 构造类的数组

Simple[] simples = new Simple[10];

新建了一个Simple数组,但是并不会导致Simple类的初始化,该操作只是在内存堆中开辟了一段连续地址空间.

引用静态[常量]不会导致该类的初始化.

类的加载阶段

类的加载就是将class的二进制读取到内存中,然后将字节流静态存储结构转换为方法去中运行的数据结构,并在堆中生成该类的Class对象,作为入口.

类加载的最终就是堆中的一个对象,不管被加载多少次,对应堆中对象始终是同一个, 在栈中形成对对象的引用.

类的连接阶段

public class LinkedPrepare {
    private static int a = 10;
    private final static int b = 10;
}

static int a = 10 在准备阶段不是10 ,而是初始化的值0,当然final static int b 则仍然是10,因为被final修饰的静态变量不会导致类的初始化

类初始化

类的初始化阶段所有的变量都会被赋予正确的值,也就是在编写程序时指定的值

静态语句块只能对后面的静态变量进行赋值,但是不能对其进行调用,否则无法通过编译.
public class classInit{
    
    static{
        System.out.print(x);
        x = 1000;
    }
    private static int x = 10;
}

类变量的赋值顺序和静态代码块的执行代码,编译器的收集顺序,由在源文件中出现顺序决定. 父类的静态变量总能优先与子类的赋值

静态代码块保证了在同一时间只会被执行一次

public class Singleton{
    // 1
    private static int x = 0;
    private static int y;
    // 2
    private static Singleton instance = new Singleton();
    
    private Singleton(){
        x++;
        y++;
    }
}

初始化结果语句放在1处,和2处的结果不同 放在2 处连接阶段, x = 0, y = 0, instaance = null; 初始化类阶段按顺序赋值真实初始化值, x = 0, y = 0, instance = new Singleton()调用构造方法 x = 1, y = 1

但是放在1 处 ,连接阶段 x = 0, y = 0 ,instance = null; 初始化阶段 instance = new Singleton() ,x = 1,y = 1 , 按顺序赋值 x = 0 ,y不变 y = 1;

类加载器

类加载器之间严格遵守父委托机制

  1. Bootsrap 根加载器

主要负责核心类库的加载,例如java.lang 包加载

  1. 扩展类加载器

扩展类加载器的父类是根加载器,主要用于加载java_home 下的jre\lib\ext里面的类库,java实现,可以将自己实现的类打包放到下面加载.

  1. 系统类加载器

负责加载classpath下的类库资源

双亲委托机制

当一个类加载器调用loadclass之后,它并不会直接将其进行加载,而是先交给当前类加载器的父加载器尝试加载直到最顶层的父加载器,然后再依次向下进行加载.

线程上下文类加载器

JVM类加载器双亲委托机制的自身缺陷,JDK提供了很多SPI,例如JDBC,JNDI接口,具体的实现有各个不同的厂家进行提供,想要更换连接器,只需要切换即可,但是例如JDBC的接口是由根加载器进行加载,但是第三方驱动则由系统类加载器加载,如何解决问题,通过 Thread的上下文加载器,允许子委托机制进行加载.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ClassLoader的结构 与 双亲委派的加载链

    1.启动类加载器,用于加载Java API,加载<JAVA_HOME>\lib目录下的类库。

    黑白格
  • java Hello world 源码执行流程详解

    hello world 作为我们学习的第一个个程序,看起来很简单,但是要理解其执行的具体流程还是需要很深的功底,包括对组成原理,操作系统的理解,今天将java ...

    黑白格
  • mysql 问题与优化

    InnoDB: 其数据文件本身就是索引文件。相比MyISAM,索引文件和数据文件是分离的,其表数据文件本身就是按B+Tree组织的一个索引结构,树的叶节点dat...

    黑白格
  • 虚拟机类加载机制(2)——类加载器

    《深入理解Java虚拟机》一书中将类的加载过程放到了类加载器前面一节,但在这里我想先讲“类加载器”。在上一篇类加载时机中我们用大量篇幅来讲解了类加载过程中的5个...

    用户1148394
  • Java 类加载机制及双亲委派模型

    即 加载 → \rightar...

    Steve Wang
  • Java虚拟机详解(十一)------双亲委派模型

      在上一篇博客,我们介绍了类加载过程,包括5个阶段,分别是“加载”,“验证”,“准备”,“解析”,“初始化”,如下图所示:

    IT可乐
  • JVM类加载器三问—虾皮真题

    我们编写的java文件会在编译后变成.class文件,类加载器就是负责加载class字节码文件,class文件在文件开头有特定的文件标识,将class文件字节码...

    码上积木
  • 原来热加载如此简单,手动写一个 Java 热加载吧

    热加载是指可以在不重启服务的情况下让更改的代码生效,热加载可以显著的提升开发以及调试的效率,它是基于 Java 的类加载器实现的,但是由于热加载的不安全性,一般...

    JAVA葵花宝典
  • JVM 学习笔记一 :JVM类加载机制

    1,类从被加载到JVM中开始,到卸载为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。

    一枝花算不算浪漫
  • 实习杂记(30):虚拟机类加载机制(3)

      每个开发人员对Java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载。Java的...

    wust小吴

扫码关注云+社区

领取腾讯云代金券