iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >JVM类加载机制过程以及原理是什么
  • 445
分享到

JVM类加载机制过程以及原理是什么

2023-07-05 02:07:48 445人浏览 独家记忆
摘要

这篇文章主要介绍“JVM类加载机制过程以及原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JVM类加载机制过程以及原理是什么”文章能帮助大家解决问题。一、做一个小测试通过注释,标注出下面两个

这篇文章主要介绍“JVM类加载机制过程以及原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JVM类加载机制过程以及原理是什么”文章能帮助大家解决问题。

    一、做一个小测试

    通过注释,标注出下面两个类中每个方法的执行顺序,并写出studentId的最终值。

    package com.nezha.javase;public class Person1 {    private int personId;    public Person1() {        setId(100);    }    public void setId(int id) {        personId = id;    }}
    package com.nezha.javase;public class Student1 extends Person1 {    private int studentId = 1;    public Student1() {    }    @Override    public void setId(int id) {        super.setId(id);        studentId = id;    }    public void getStudentId() {        System.out.println("studentId = " + studentId);    }}
    package com.nezha.javase;public class Test1 {    public static void main(String[] args) {        Student1 student = new Student1();        System.out.println("new Student() 完毕,开始调用getStudentId()方法");        student.getStudentId();    }}

    有兴趣的小伙伴试一下,相信我,用System.out.println标记一下每个函数执行的先后顺序,如果你全对了,下面的不用看了,大佬。

    二、类的初始化步骤:

    • 初始化父类中的静态成员变量和静态代码块 ;

    • 初始化子类中的静态成员变量和静态代码块 ;

    • 初始化父类的普通成员变量和代码块,再执行父类的构造方法;

    • 初始化子类的普通成员变量和代码块,再执行子类的构造方法;

    三、看看你写对了没?

    package com.nezha.javase;public class Person {    private int personId;        public Person() {        // 1、第一步,走父类无参构造函数        System.out.println("第一步,走父类无参构造函数");        System.out.println("");        setId(100);    }        public void setId(int id) {        System.out.println("第三步,通过super.setId(id);走父类发方法~~~id="+id);        personId = id;        System.out.println("在父类:studentId 被赋值为 " + personId);        System.out.println("");    }}
    package com.nezha.javase;public class Student extends Person {    private int studentId = 1;        public Student() {        System.out.println("第五步,在走子类无参构造函数前,会先执行子类的普通成员变量初始化");        System.out.println("第六步,走子类无参构造函数");        System.out.println("");    }        @Override    public void setId(int id) {        System.out.println("第二步,走子类方法~~id="+id);        // 3、第三步,走子类方法        super.setId(id);        studentId = id;        System.out.println("第四步,再回此方法,在子类:studentId 被赋值为 " + studentId);        System.out.println("");    }        public void getStudentId() {        // 4、打印出来的值是100        System.out.println("第七步,走getStudentId()");        System.out.println("studentId = " + studentId);        System.out.println("");    }}
    package com.nezha.javase;public class Test1 {    public static void main(String[] args) {        Student1 student = new Student1();        System.out.println("new Student() 完毕,开始调用getStudentId()方法");        // 打印出来的值是100        System.out.println("#推测~~打印出来的值是100");        student.getStudentId();    }}

    JVM类加载机制过程以及原理是什么

    下面通过图解JVM的方式,分析一下。

    四、类的加载过程

    JVM类加载机制过程以及原理是什么

    加载

    • 通过一个类的全限定名获取定义此类的二进制字节流;

    • 将这个字节流代表的静态存储结构转化为方法区的运行时数据结构

    • 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;

    链接

    (1)验证(Verify)

    • 目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全

    • 主要包括四种验证:文件格式验证、元数据验证、字节码验证、符号引用验证;

    (2)准备(Prepare)

    • 为类变量分配内存并且设置该类变量的默认初始值;

    • 这里不包含final修饰的static,因为final在编译的时候就会分配了,准备阶段会显示初始化;

    • 这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到堆中;

    (3)解析

    • 将常量池内的符号引用转换为直接引用的过程

    • 例如静态代码块、静态变量的显示赋值

    • 事实上,解析操作往往会伴随着JVM在执行完初始化之后在执行

    • 符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《Java虚拟机规范》的Class文件格式中。直接引用就是指- 向目标的指针、相对偏移量或一个间接定位到目标的句柄

    • 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。对常量池中的CONSTANT_Filedref_info、CONSTANT_Class_info、CONSTANT_Methodref_info等。

    初始化

    • 初始化阶段就是执行类构造器方法的过程;

    • 此方法不需要定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来;

    • 构造器方法中指令按语句在源文件中出现的顺序执行;

    • 类构造器方法不同于类的构造器。构造器是虚拟机视角下的类构造器;

    • 若该类具有父类,JVM会保证子类的类构造器执行前,父类的类构造器已经执行完毕;

    • 虚拟机必须保证一个类的类构造器方法在多线程下被同步加

    五、类加载器的分类

    JVM类加载器包括两种,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)。

    所有派生于抽象类ClassLoader的类加载器划分为自定义类加载器。

    1、启动类加载器(引导类加载器)

    • 启动类加载器是使用C/C++语言实现的,嵌套在JVM内部;

    • Java的核心类库都是使用引导类加载器加载的,比如String;

    • 没有父加载器;

    • 是扩展类加载器和应用程序类加载器的父类加载器 ;

    • 出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类 ;

    JVM类加载机制过程以及原理是什么

    2、扩展类加载器

    • java语言编写

    • 派生于ClassLoader类

    • 父类加载器为启动类加载器

    • 从java.ext.dirs系统属性所指定的目录中加载类库,或从jdk的安装目录jre/lib/ext子目录(扩展目录)下加载类库。如果用户创建的jar放在此目录下,也会自动由扩展类加载器加载

    JVM类加载机制过程以及原理是什么

    3、应用程序类加载器(系统类加载器)

    1. java语言编写

    2. 派生于ClassLoader类

    3. 父类加载器为扩展类加载器

    4. 它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库

    5. 该类加载器是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载的

    6. 通过ClassLoader.getSystemClassLoader()方法可以获得该类加载器

    六、类加载器子系统的作用

    JVM类加载机制过程以及原理是什么

    类加载器子系统负责从文件系统或网络中加载class文件,class文件在文件开头有特定的文件标识。

    ClassLoader只负责class文件的加载,至于它是否可以运行,则有执行引擎决定。

    加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池的信息,可能还包括字符串字面量和数字常量(这部分常量信息是class文件中常量池部分的内存映射)。

    关于“JVM类加载机制过程以及原理是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

    --结束END--

    本文标题: JVM类加载机制过程以及原理是什么

    本文链接: https://www.lsjlt.com/news/349131.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • c++中if elseif使用规则
      c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
      99+
      2024-05-14
      c++
    • c++中的继承怎么写
      继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
      99+
      2024-05-14
      c++
    • c++中如何使用类和对象掌握目标
      在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
      99+
      2024-05-14
      c++
    • c++中优先级是什么意思
      c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
      99+
      2024-05-14
      c++
    • c++中a+是什么意思
      c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
      99+
      2024-05-14
      c++
    • c++中a.b什么意思
      c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
      99+
      2024-05-14
      c++
    • C++ 并发编程库的优缺点
      c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
      99+
      2024-05-14
      c++ 并发编程
    • 如何在 Golang 中备份数据库?
      在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
      99+
      2024-05-14
      golang 数据库备份 mysql git 标准库
    • 如何在 Golang 中优雅地处理错误?
      在 go 中,优雅处理错误包括:使用 error 类型;使用 errors 包函数和类型;自定义错误类型;遵循错误处理模式,包括关闭资源、检查错误、打印错误信息和处理或返回错误。 在 ...
      99+
      2024-05-14
      golang 错误处理
    • 如何构建 Golang RESTful API,并使用中间件进行身份验证?
      本文介绍了如何构建 golang restful api。首先,通过导入必要的库、定义数据模型和创建路由来构建 restful api。其次,使用 go-chi/chigot 和 go-...
      99+
      2024-05-14
      golang git
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作