类加载和类加载器

什么是类加载

类加载指的是将.Class文件读入内存,并为之创建一个java.lang.Class对象,也就是说程序使用任何类时,系统都会为之建立一个java.lang.Class对象

何时类加载和类加载步骤

当程序主动使用某个类时,系统会通过加载,连接,初始化三个步骤来对该类进行初始化,JVM将会连续完成这三个步骤,也把这三个步骤统称为类加载或类初始化。

主动触发类加载的情况

1)创建类的实例,也就是new一个对象

2)访问某个类或接口的静态变量,或者对该静态变量赋值

3)调用类的静态方法

4)反射(Class.forName("com.lyj.load"))

5)初始化一个类的子类(会首先初始化子类的父类)

6)JVM启动时标明的启动类,即文件名和类名相同的那个类

类加载步骤

1) 装载:查找并加载类的二进制数据;

2)链接:

  验证:确保被加载类的正确性;

  准备:为类的静态变量分配内存,并将其初始化为默认值;

  解析:把类中的符号引用转换为直接引用;

3)初始化:为类的静态变量赋予正确的初始值;

准备阶段和初始化阶段的解释: 如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a    是static的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析(后面在说),到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10。

类加载器

1.Bootstrap( 加载系统类):  c++写的, 该类不能访问

      加载路径:  %JAVA_HOME%/jre/lib ,  sun.boot.class.path 指向的目录或jar , %JAVA_HOME%/jre/classes中的类

2. ExtClassLoader ( 加载扩展类):   java写的静态内部类,具体实现是   sun.misc.Launcher$ExtClassLoader

        加载路径:   %JAVA_HOME%/jre/lib/ext  ,   java.ext.dirs 指向的目录或jar

3. AppClassLoader类(加载应用类) :  是Java程序默认的类加载器,  java写的 静态内部类,具体实现是 sun.misc.Launcher$AppClassLoader

         加载路径:   java.class.path 指向的目录或jar

一个项目中需要加载的类:

1.javaAPI:如String类

2.外部的jar:比如sprin框架

3.自定义的:

  1)自己写的类

2)继承javaAPI,自己的实现代替javaAPI

三者之间的关系是

  1. Bootstrap是爷爷、ExtClassLoader是爸爸、AppClassLoader是孩子(孙子)

2. ExtClassLoader和AppClassLoader都是由Bootstrap加载的:

    虚拟机初始化动作完成后,会产生第一个类加载器 Bootstrap Loader ,Bootstrap Loader会加载 ExtClassLoader 并设定其 Parent 为 null ,代表其父加载器为 BootstrapLoader
    然后Bootstrap Loader 再要求加载 AppClassLoader 并设定其 Parent 为之前产生的 ExtClassLoader 实体

加载器加载的二进制数据来源

1)从本地系统直接加载Class文件,如放在了bin目录下

2)通过网络下载.class文件

3)从zip,jar等归档文件中加载.class文件,如JDBC编程时用到的数据库驱动类就是放在jar文件中,JVM可以从jar文件中直接加载该Class文件

4)从专有数据库中提取.class文件

5)将Java源文件动态编译为.class文件(服务器)

时间: 2024-08-08 05:20:33

类加载和类加载器的相关文章

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

深入JVM系列(三)之类加载.类加载器.双亲委派机制与常见问题 http://blog.csdn.net/vernonzheng/article/details/8461380 转--深入JVM系列(三)之类加载.类加载器.双亲委派机制与常见问题

Java重要技术(28)类加载器之类加载器的层次关系和委托加载机制

1.1. 类加载器的层次 类加载器包括三种: Bootstrap ClassLoader:用于加载JRE的lib目录下的jar文件中的class. ExtClassLoader:用于加载JRE的lib/ext目录下的jar文件中的class. AppClassLoader:用于加载classpath下的class. 在加载一个class时,通常应该先委托给parent类加载器来加载,parent类加载器找不到这个类时,才自行加载.实际优先次序从高到低排列是BootStrap ClassLoade

Java重要技术(29)类加载器之类加载器的职责

1.1. 类加载器的职责 每个类(Class)都有一个类加载器.类加载器ClassLoader的职责包括以下内容: (1)类的定位.根据类的名称找到对应的class文件,也可以不需要class文件. (2)类的定义.产生表达类的定义的Class类的实例. 某个Sample类的代码如下: package com.test.javatechnology.classloader.test; //Sample类的class文件将位于test目录下. public class Sample { //NOT

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

一.概述 定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型.类加载和连接的过程都是在运行期间完成的. 二. 类的加载方式 1):本地编译好的class中直接加载 2):网络加载:java.net.URLClassLoader可以加载url指定的类 3):从jar.zip等等压缩文件加载类,自动解析jar文件找到class文件去加载util类 4):从java源代码文件动态编译成为class文件 三.类加载的时机

虚拟机类加载机制--类加载器

准备阶段的"通过一个类的全限定名来获取描述此类的二进制字节流"这个动作放到了Java虚拟机外部去实现,以便让应用程序自己决定如何如获取所需要的类.实现这个动作的代码模块称为"类加载器" 1.类与类加载器 每一个类加载器都有一个独立的类名称空间,由类加载器和类一起合作才能确定一个类在虚拟机中的唯一性.也就是说:比较两个类是否"相等",即使他们来自同一个Class文件,在同一个虚拟机上被加载,如果加载它们的类加载器不同,那么这两个类就不相等. 这里的

JVM类加载机制---类加载的过程

一.类加载的时机 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用.卸载 7个阶段,其中验证.准备.解析 3个部分统称为 连接. 二.具体步骤解析 1.加载 加载阶段,虚拟机要完成以下3件事情: 1)通过一个类的全限定名来获取定义此类的二进制字节流: 2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构: 3)在内存中生成一个代表这个类的java.lang.class对象,作为方法区这个类的各种数据的访问入口. 相对于类加载过

虚拟机类加载机制------类加载的过程

1.加载 虚拟机需要干三件事: ①.通过一个类的的全限定名来获取定义此类的二进制字节流(没有规定二进制字节流从那里获取,怎样获取,许多java技术也都建立在这基础上) ②将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构(将常量池转变成运行时常量池) ③在内存中生成一个代表这个类的java.lang.Class对象,作为方法区着各类的各种数据的访问入口. 相比较于类加载过程的其他阶段,非数组类获取类的二进制字节流的动作是开发人员可控性最强的,因为加载阶段既可以使用系统提供的引导类加载器

Jvm(56),虚拟机类加载机制----类加载的过程----初始化

类初始化阶段是类加载过程的最后一步,前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制.到了初始化阶段,才真正开始执行类中定义的Java程序代码(或者说是字节码). 在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源,或者可以从另外一个角度来表达:初始化阶段是 执行类构造器<clinit>()方法的过程.我们在下文会讲解<clinit>()方法是怎么生成的

Jvm(55),虚拟机类加载机制----类加载的过程----解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,符号引用在前一章讲解 Class文件格式的时候已经出现过多次,在Class文件中它以CONSTANT_Class_info. CONSTANT_Fieldref_info.CONSTANT_Methodref_info等类型的常量出现,那解析阶段中所说的直接引用与符号引用又有什么关联呢? 符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可