java类的加载过程详细解释(图文结合)

java类的加载过程是什么 类加载主要是由jvm虚拟机负责的,过程比较复杂,java文件从编码到最终执行一般主要包括两个过程: 编译—》运行

而我们所说的类加载过程即是指JVM虚拟机把.class文件中类信息加载进内存,并进行解析生成对应的class对象的过程。

    类加载过程 类加载分三步:加载(双亲委派模型)—》连接—》初始化 加载(靠加载器完成,明白加载机制)** Jdk提供的三种类加载器: 1) BootstrapClassLoader(启动类/引导类/根加载器):主要加载JAVA_HOME/jre/lib里的jar包,该目录下的所有jar包都是运行jvm是所必需的jar包。如果一个类的加载器是BootstrapClassLoader,那么该类的getClassLoader()方法返回null。 2) ExtClassLoader(扩展类加载器):主要加载java核心扩展类,即JAVA_HOME/jre/ext目录下的jar文件。 3) AppClassLoader(应用类加载器):主要加载开发者在应用编程中编写的类,即CLASSPATH路径下的jar文件。 三中类加载器的关系如下: 案例:将用户自定义的people类所在的源文件一jar包的形式放到ExtClassLoader加载类路径下,调用people类的getClassLoader()方法,返回的是ExtClassLoader还是AppClassLoader类加载器,还是两个都返回? 答案是:一个普通的people类,返回AppClassLoader,放在ExtClassLoader 类加载路径下进行加载,返回的是ExtClassLoader,原因如下: 可以看到这里提到了双亲委派模型,具体使用双亲委派模型的好处如下: 1)安全性:避免用户自己编写的类动态替换java的一些核心类。如果不采用双亲委派模型的加载方式进行类的加载工作,那就可以随时用自定义的类来动态代替java核心API中定义的类,例如:如果黑客将“病毒代码”植入到自定义的String类中,随后类加载器将自定义的String类加载到JVM上,此时就会对JVM产生意想不到的“病毒攻击”,而双亲委派模型的这种加载可以避免这种情况,因为String类已经在启动时就被引导类加载器进行了加载。 2)避免类的重复加载,因为JVM判断两个类是否是同一类,不仅仅根据类名进行判断,还需要判断加载该类的类加载器是否是同一类加载器,相同的class文件被不同的类加载器加载得到的结果就是两个不同的类。 重写的三个方法: 连接(验证、准备、解析) 连接阶段负责把类的二进制数据合并到JRE中,三个阶段: 1) 验证(文件格式验证、元数据、字节码、符号引用):确保(加载的类信息)Class文件的字节流中包含的信息符合当前虚拟机的要求,并不会危害虚拟机自身的安全。 2) 准备:准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。内存分配的只包括被Static修饰的变量,不包括实例变量,实例变量在对象实例化时随着对象一期分配在java堆中。(也就是为静态文件分配内存,并设置初始值)。通常情况下初始值为0值。 3) 解析:是虚拟机将常量池中的符号引用替换为直接引用的过程(将类的二进制数据中的符号引用替换成直接引用)。 初始化 初始化是类加载过程中的最后一步,在准备阶段变量已经赋过一次系统要求的初始值,在初始化阶段,则是根据程序员通过程序制定的主观计划初始化变量和其他资源。 总结 类的加载是一个常见的问题,可以通过书籍或者他人博客进行知识点详细总结,更加深入的了解类的加载过程。
经验分享 程序员 微信小程序 职场和发展