Java类加载机制

简介: Java类加载机制

Java类加载机制

1.java类加载基本分为三部分:

1. 装载
2. 链接
    1. 验证
    2. 准备
    3. 解析
3. 初始化

1. 加载:
加载就是通过指定的类全限定名,获取此类的二进制字节流,然后将此二进制字节流转化为方法区的数据结构,在内存中生成一个代表这个类的Class对象。

JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:

1.Bootstrap ClassLoader:
    负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
2. Extension ClassLoader:
    负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
3. App ClassLoader:
    负责记载classpath中指定的jar包及目录中class
4. Custom ClassLoader:
    属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader。
    加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只被ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
2. 验证:
为了确保Class文件中的字节流符合虚拟机的要求,并且不会危害虚拟机的安全.
3. 准备:
1. 这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在Java堆中。
2. 这里所设置的初始值通常情况下是数据类型默认的零值(如0、0L、null、false等),而不是被在Java代码中被显式地赋予的值。
4. 解析:
把类中的符号引用转换为直接引用。
5. 初始化:
1. 编译器会自动收集类中的所有静态变量(类变量)和静态语句块(static{}块)中的语句合并产生的,编译器收集的顺序是根据语句在java代码中的顺序决定的。
2. 收集完成之后,会编译成java类的 static{} 方法,java虚拟机则会保证一个类的static{} 方法在多线程或者单线程环境中正确的执行,并且只执行一次。在执行的过程中,便完成了类变量的初始化。如果只有静态变量,编译器会默认生成一个static{}
3. 执行完类变量后,再执行实例变量,以及普通代码块。
4. 简单来说:初始化阶段是执行类构造器<clinit>()方法的过程。
5. 调用类构造器<clinit>()方法,也是对成员变量进行赋值的时候.

2.举例演示

1. 代码:
public class Base {
private String name = "hello";
    public Base() {
//      System.out.println(this);
//      关键是要认识到调用callName方法的是sub类型的对象
        callName();
}
    public void callName(){
        System.out.println(name);
    }
    public static void main(String[] args) {
        new Sub();
    }
}
class Sub extends Base{
    private String name="world";
    public Sub(){
        callName();
    }
    public void callName(){
        System.out.println(name);
    }
}
2. 分析:
    1. 加载:由加载器进行加载类,ClassLoader及其子类来完成。
    2. 验证:由于是JVM自动生成的java类对象,并不存在安全问题。
    3. 准备:为静态变量分配内存空间,及设置其为的默认属性值
    4. 解析:把类中的符号引用转换为直接引用。
    5. 初始化 :
        1. 先执行父类,发现没有静态变量,也没有静态代码块。
        2. 执行父类的构造器的同时,为父类的name赋值,执行callName()方法
        3.  由于子类重写父类的构造器,所以调用子类的callName(),子类的构造器没有执行过,所以的name没有赋值过,是默认值。
        4.  再执行子类构造器,这时name值已经被赋值过。
    6. 答案: null
            world

关注公众号:熊猫Jay字节之旅,了解更多 AI 技巧 ~

相关文章
|
8月前
|
安全 Java 程序员
学习Java类加载机制
在Java的世界里,每一个类或者接口,在经历编译器后,都会生成一个个.class文件。
54 0
|
8月前
|
Java
一个表格带你搞懂java的类加载机制
一个表格带你搞懂java的类加载机制,加载->验证->准备->解析->初始化->使用.卸载
|
SQL 前端开发 Java
大数据平台底层技术-JAVA篇-如何动态加载不同版本的 HIVE JDBC 驱动 - 一文读懂JAVA的类加载机制 1
大数据平台底层技术-JAVA篇-如何动态加载不同版本的 HIVE JDBC 驱动 - 一文读懂JAVA的类加载机制
|
5月前
|
存储 Java 数据库连接
Java类文件结构及类加载机制
该文章主要讨论了Java类文件的结构以及Java类的加载机制,并提到了双亲委派模型的相关内容。
Java类文件结构及类加载机制
|
5月前
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
78 0
|
5月前
|
安全 前端开发 Java
【JVM 探秘】ClassLoader 类加载器:揭秘 Java 类加载机制背后的秘密武器!
【8月更文挑战第25天】本文全面介绍了Java虚拟机(JVM)中的类加载器,它是JVM的核心组件之一,负责将Java类加载到运行环境中。文章首先概述了类加载器的基本工作原理及其遵循的双亲委派模型,确保了核心类库的安全与稳定。接着详细阐述了启动、扩展和应用三种主要类加载器的层次结构。并通过一个自定义类加载器的例子展示了如何从特定目录加载类。此外,还介绍了类加载器的完整生命周期,包括加载、链接和初始化三个阶段。最后强调了类加载器在版本隔离、安全性和灵活性方面的重要作用。深入理解类加载器对于掌握JVM内部机制至关重要。
188 0
|
6月前
|
Java 程序员 开发者
Java中的类加载机制详解
Java中的类加载机制详解
|
7月前
|
存储 前端开发 Java
深入解析Java类加载机制:原理、过程与实践
深入解析Java类加载机制:原理、过程与实践
242 2
|
6月前
|
前端开发 Java 数据安全/隐私保护
深入理解Java中的类加载机制
深入理解Java中的类加载机制
|
7月前
|
前端开发 Java 开发者
Java中的类加载机制与双亲委派模型
Java中的类加载机制与双亲委派模型