转自博客:https://blog.csdn.net/weixin_38118016/article/details/79579657

文章不是我写的,但是感觉写的挺通俗易懂的,然后防止以后丢失,就转载到我的个人博客上了,留作学习笔记。

零、Java的编译执行过程

编译  -----> 验证   -----> 准备   ----->解析 ----->初始化 ----->使用------>卸载

其中验证、准备、解析统称为连接

1.编译:    将   .java 文件 通过 javac  文件名.java 的命令  编译成  文件名 .class 的过程

2.验证:   确保Class文件的字节流中包含的信息符合当前虚拟机的要求。

3.准备:   正式为类变量(被static修饰的变量,不包括实例变量,实例变量在对象实例化时随对象分配到java堆中)分配内存并设置类变量初始值,且初始值是指数据类型的零值。

4.解析:   将常量池内的符号引用替换为直接引用

5.初始化: 执行类构造器<clinit>()方法的过程,<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的。

附:静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块中可以赋值但不能访问

 public class Test {

     static {
i = 0; //给变量赋值可以正常通过
System.out.println(i); //错。编译器提示“非法向前引用”
}
static int i =1;
}

有五种情况必须初始化(加载、连接自然要在这之前进行)

1.遇到new、getstatic、putstatic或invokestatic这四条字节码指令时

2.使用java.lang.reflect包的方法对类进行反射调用的时候

3.当初始化一个类时,如果父类还没有进行初始化,需要先触发其父类的初始化

4.当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的类),虚拟机会先初始化这个类

5.当使用jdk1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,需要先初始化

这五种称为对一个类的主动引用,除此之外的都不会触发初始化,称为被动引用。

例:

1.通过子类引用父类的静态字段,不会导致子类的初始化

2.通过数组定义来引用类

3.常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会初始化

一、java类加载器分类详解

  1、Bootstrap ClassLoader:

      启动类加载器,也叫根类加载器,负责加载java的核心类库,例如(%JAVA_HOME%/lib)目录下的rt.jar(包含System,String这样的核心类),根类加载器非常特殊,它不是java.lang.ClassLoader的子类,它是JVM自身内部由C/C++实现的,并不是java实现的

  2、Extension ClassLoader:

      扩展类加载器,负责加载扩展目录(%JAVA_HOME%/jre/lib/ext)下的jar包,用户可以把自己开发的类打包成jar包放在这个目录下即可扩展核心类以外的功能

 3、System ClassLoader\APP ClassLoader:

      系统类加载器,又称为应用程序类加载器,是加载CLASSPATH环境变量下所指定的jar包与类路径,一般来说,用户自定义的就是由APP ClassLoader加载的

       各类加载器之间的关系       以组合关系复用父类加载器的父子关系,注意,这里的父子关系并不是以继承关系实现的

二、类加载器的双亲委派加载机制(重点)

    当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载都是如此,因此所有的加载请求都应该传送到启动类加载器中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径里找不到这个所需要加载的类),子类加载器才会尝试自己去加载

过程如下图所示:

  

三、双亲委派模型的源码实现

  主要体现在ClassLoader的loadClass()方法,思路很简单:

    先检查是否已经被加载,若没有被加载则调用父类的LoadClass()方法,若父类加载器为空,则默认使用启动类加载器作为父类加载器,如果父类加载器加载失败,抛出ClassNotFoundException异常后,调用自己的findClass()方法进行加载

Java 基础 类加载器和双亲委派机制 学习笔记的更多相关文章

  1. Java虚拟机类加载器及双亲委派机制

    所谓的类加载器(Class Loader)就是加载Java类到Java虚拟机中的,前面<面试官,不要再问我"Java虚拟机类加载机制"了>中已经介绍了具体加载class ...

  2. Java类加载器和双亲委派机制

    前言 之前详细介绍了Java类的整个加载过程(类加载机制详解).虽然,篇幅较长,但是也不要被内容吓到了,其实每个阶段都可以用一句话来概括. 1)加载:查找并加载类的二进制字节流数据. 2)验证:保证被 ...

  3. Java自定义类加载器与双亲委派模型

    其实,双亲委派模型并不复杂.自定义类加载器也不难!随便从网上搜一下就能搜出一大把结果,然后copy一下就能用.但是,如果每次想自定义类加载器就必须搜一遍别人的文章,然后复制,这样显然不行.可是自定义类 ...

  4. 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题

    一.概述   定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型.类加载和连接的过程都是在运行期间完成的. 二. 类的 ...

  5. Java基础知识-简明阐述双亲委派机制及作用

    1.双亲委派机制及作用 1.1 什么是双亲委派机制 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类 ...

  6. 【Java_基础】java类加载过程与双亲委派机制

    1.类的加载.连接和初始化 当程序使用某个类时,如果该类还未被加载到内存中,则系统会通过加载.连接.初始化三个步骤来对类进行初始化.如果没有意外,jvm将会连续完成这三个步骤,有时也把这三个步骤统称为 ...

  7. 类文件的结构、JVM 的类加载过程、类加载机制、类加载器、双亲委派模型

    一.类文件的结构 我们都知道,各种不同平台的虚拟机,都支持 "字节码 Byte Code" 这种程序存储格式,这构成了 Java 平台无关性的基石.甚至现在平台无关性也开始演变出 ...

  8. JVM类加载机制详解(二)类加载器与双亲委派模型

    在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有: 1.通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件).而获取的方式,可 ...

  9. 深入理解java虚拟机(九)类加载器以及双亲委派模型

    虚拟机把类加载阶段中“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到虚拟机外部去实现,以便让程序自己决定如何去获取所需要的类.实现这个动作的代码模块称为“类加载器”. 类与类加载器 任 ...

随机推荐

  1. 关于 ubuntu 下 防火墙 ufw的使用

    ufw 是 iptables 的一个语法糖.详细介绍

  2. 传纸条---(dp)

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个mmm行nnn列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了. ...

  3. vue利用vue ui命令创建项目

    上次用git bash,用create 命令创建vue项目,这是玩个炫酷的------vue ui (前提是有安装node.js). 在目标文件  vue ui 可以看到他在8000端口出现了一个gu ...

  4. Navicat导入sql server数据库

    1.新建连接 2. EXEC sp_attach_db @dbname = 'demo',   (数据库的名字) @filename1 = 'G:\C#\超市管理系统\DB\CSGL.mdf', @f ...

  5. jq 点击按钮显示div,点击页面其他任何地方隐藏div

    css .bl_rencai_32{ float: left; height: 35px; line-height: 35px; } .bl_rencai_32 >input{ width: 3 ...

  6. mysql5.7.17安装配置图文教程

    My SQL的特点: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,M ...

  7. svn和NetBeans一起使用造成svn老是死锁, database is locked

    其实我一直没发现,又一次我以为需要写些前端吧NetBeans关了,使用HBuilder写vue,因为内存只有8G,乱七八糟的一些东西一开,只剩20%左右,我就把 NetBeans关了,发现更新svn的 ...

  8. maven依赖和传递

    compile (编译范围) compile是默认的范围:如果没有提供一个范围,那该依赖的范围就是编译范围.编译范围依赖在所有的classpath 中可用,同时它们也会被打包. 只有compile 才 ...

  9. 《PHP - CGI/Fastcgi/PHP-FPM》

    先说下我最近看到的一篇文章,哈哈哈,特别好玩. 一步步教你编写不可维护的 PHP 代码 之前一直知道 PHP 在 CGI 模式下运行.命令行下在 CLI 模式下运行. 但是 FPM 和 nginx 配 ...

  10. Spring之IOC注入

    注入 spring依赖注入 set方法: <property name="属性名" values ="值">--ref="对象名" ...