1.概述

类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行,对理解java虚拟机的连接模型和java语言的动态性都有很大帮助。

由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。

JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类。

2.类加载器

类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader的子类)。

  • Bootstrap:一般用本地代码实现,负责加载JVM基础核心类库(rt.jar);

  • Extension:从java.ext.dirs系统属性所指定的目录中加载类库,它的父加载器是Bootstrap;

  • System:又叫应用类加载器,其父类是Extension。它是应用最广泛的类加载器。它从环境变量classpath或者系统属性java.class.path所指定的目录中记载类,是用户自定义加载器的默认父加载器。

3.类加载的过程

JVM类加载机制

<1>全盘负责,当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入

<2>父类委托,先让父类加载器试图加载该类,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类

<3>缓存机制,缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区寻找该Class,只有缓存区不存在,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓存区。这就是为什么修改了Class后,必须重启JVM,程序的修改才会生效。

双亲委派模型的工作流程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

下图是我总结的一个java类被jvm加载的过程。

4.子类和父类加载顺序

那么问题来了,如果有一个java类继承了另一个java类,这两个类的内部具体的执行过程是什么呢?

比如下面的面试题:

public class Tests{

@Test public void test(){

A a= newA(); a.aDisplay();

}

}

执行结果:

Class B1:static blocks2 Class B2:static blocks3

Class A1:static blocks1 Class A2:static blocks2

Class B:common blocksi=4,j=3 constructorB: i=5,j=4

Class A:common blocksi=3,j=2 constructorA: i=4,j=3

Class A:static void a Display(): i=5,j=3

可能这里面最迷惑人的就是两个成员变量了,一个静态的一个非静态的。

其实他们出现在这是貌似没啥太大意义,父类和子类虽然拥有着同名的成员变量,但是,这些变量都独自存在于各自的类中,并有各自的只。

言归正传,由上面的面试题,我们可以得出下面的规律:

从经典面试题看java中类的加载机制的更多相关文章

  1. Java中类的加载、连接和初始化

    Java中类的加载.连接和初始化 类的加载.连接和初始化 先介绍一下JVM和类 JVM和类: 当我们调用Java命令运行某个Java程序时,该命令将会启动一个Java虚拟机进程,不管该Java程序有多 ...

  2. java 中类的加载顺序(转)

    1.虚拟机在首次加载Java类时,会对静态初始化块.静态成员变量.静态方法进行一次初始化 2.只有在调用new方法时才会创建类的实例 3.类实例创建过程:按照父子继承关系进行初始化,首先执行父类的初始 ...

  3. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

  4. JVM(1):Java 类的加载机制

    原文出处: 纯洁的微笑 java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang. ...

  5. java类的加载机制

    什么是类装载器ClassLoader ClassLoader是一个抽象类 ClassLoader的实例将读入Java字节码将类装载到JVM中 ClassLoader可以定制,满足不同的字节码流获取方式 ...

  6. Java实现配置加载机制

    前言 现如今几乎大多数Java应用,例如我们耳熟能详的tomcat, struts2, netty…等等数都数不过来的软件,要满足通用性,都会提供配置文件供使用者定制功能. 甚至有一些例如Netty这 ...

  7. Java 中类的加载顺序

    如果类A和类B中有静态变量,静态语句块,非静态变量,非静态语句块,构造函数,静态方法,非静态方法,同时类A继承类B,请问当实例化A时,类内部的加载顺序是什么? 测试代码如下: Class B: pub ...

  8. java中类的加载顺序介绍(ClassLoader)

    转自:http://blog.csdn.net/eff666/article/details/52203406 1.ClassNotFoundExcetpion  我们在开发中,经常可以遇见java. ...

  9. JVM:Java 类的加载机制

    虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验,转换,解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制. 类的生命周期 类从被加载到虚拟机内 ...

随机推荐

  1. Quatz入门

    Demo SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory(); Scheduler sched = sched ...

  2. 九度 1254:N皇后问题

    Leetcode 原题. 这里 N 最大会取到 13, TLE 了 代码 #include <iostream> #include <stdio.h> using namesp ...

  3. Log4net用法(.config文件)

    1.引用log4net.dll 2.在AssemblyInfo.cs中添加初始化: [assembly: log4net.Config.XmlConfigurator(ConfigFile = &qu ...

  4. Oracle基本操作,Oracle修改列名,Oracle修改字段类型

    oracle基本操作,Oracle修改列名,Oracle修改字段类型 >>>>>>>>>>>>>>>>& ...

  5. scala中list集合的操作与总结

    /** * Created by root * Description : List */ object ListTest { def main(args: Array[String]): Unit ...

  6. Web暴力破解--前端JS表单加密进行爆破

    0x01 前言 常见的js实现加密的方式有:md5.base64.shal,写了一个简单的demo作为测试. 0x02 代码 login.html <!DOCTYPE HTML> < ...

  7. Bypass ngx_lua_waf SQL注入防御(多姿势)

    0x00 前言 ​ ngx_lua_waf是一款基于ngx_lua的web应用防火墙,使用简单,高性能.轻量级.默认防御规则在wafconf目录中,摘录几条核心的SQL注入防御规则: select.+ ...

  8. Struts2开发模式漏洞

    当Struts2中的devMode模式设置为true时,存在严重远程代码执行漏洞.如果WEB服务以最高权限运行时,可远程执行任意命令,包括远程控制服务器. 如果为受影响的版本,建议修改配置文件stru ...

  9. Unity3D Shader官方教程翻译(十九)----Shader语法,编写表面着色器

    Writing Surface Shaders Writing shaders that interact with lighting is complex. There are different ...

  10. 操作系统定期定时执行python脚本

    1. Windows 控制面板 --> 管理工具 -->任务计划程序 --> 创建任务 接下来就是设置执行的时机以及脚本路径等 1>>常规 设置任务名称描述,以及是否执行 ...