转自博客: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. Java 中数据库连接池的比较

    见 原文,现阶段建议使用 https://github.com/brettwooldridge/HikariCP

  2. C/C++预处理器

    关于预处理器 首先时预处理器的条件指令 什么是预处理指令? 预处理指令是以#号开头的代码行.#号必须是该行除了任何空白字符外的第一个字符.#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符 ...

  3. linux samba建立共享文件夹

    sudo  apt-get install samba 1.  mkdir  /home/lgs/samba_share    (/home/lgs为自己的家目录) 2.  find    -name ...

  4. 泡泡一分钟:Semantic Labeling of Indoor Environments from 3D RGB Maps

    张宁 Semantic Labeling of Indoor Environments from 3D RGB Maps Manuel Brucker,  Maximilian Durner,  Ra ...

  5. Consul部署架构

    Consul 使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接,用于实现分布式系统的服务发现与配置. 应用Consul提供的服务需要建立Consul集群.在Consul方案中,每个 ...

  6. python2,python3同时安装时,python3可以安装并升级pip库,python2报错的解决办法

    最近在使用pip安装包的的时候出现下面错误 UnicodeEncodeError: 'ascii' codec can't encode character u'\u258f' 查询资料后发现原因是p ...

  7. Mycat原理、应用场景

    Mycat原理 Mycat的原理并不复杂,复杂的是代码,如果代码也不复杂,那么早就成为一个传说了.Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一 ...

  8. 《Mysql 数据类型》

    一:整型 - 常用类型 类型 占用(字节) 范围 无符号范围 无符号范围 TINYINT 2的8次方 - — — SMALLINT 2的15次方 - — 6553 5 INT 2的31次方 - — 4 ...

  9. oracle 新建用户后赋予的权限语句

    grant create session,resource to itsys; grant create table to itsys;grant resource to itsys;grant cr ...

  10. es6阮一峰读后感

    不经意间看了你一眼(阮一峰的es6读后感)我自己常用的 字符串篇:ES6 为字符串添加了遍历器接口(详见<Iterator>一章),使得字符串可以被for...of循环遍历.只要有遍历器接 ...