Java类的加载与生命周期
一、概要:
类的生命周期从类的 加载、连接、初始化 开始,到类的 卸载结束;
二、几个阶段:
加载:查找并加载类的二进制数据。(把类的.class文件的二进制数据读入内存,存放在运行时数据区的方法区;类加载的最终结果是产生 堆区中描述对应类的Class对象);
连接:包括验证、准备和解析三个子阶段;
验证:确保补加载类的正确性;
准备:为类的静态变量分配内存,并设定默认值;
解析:把类中的符号引用转换为直接引用;
初始化:给类中的静态变量赋予正确的初始值;
类的加载时机:并不需要等到某个类被主动使用时才加载,虚拟机会预测某个类将要被使用就加载它;
类的初始化时机:
a. 创建类(new、反射、克隆、反序列化)
b. 使用静态方法、非静态变量
c. Class.forName("ATest"); 获取描述类的Class对象;
另:初始化子类,父类被先初始化。虚拟机的启动类,使用命令 java Sample(也算是创建类);
注:
使用能在编译期能得知的final static修饰的常量,不会导致类的初始化;
public static final int a = 2*3;//编译时常量,不会导致类初始化;
public static final int a b = (int)(Math.random()*10)/10+1; // 不是编译时常量,会初始化;
只有当程序访问的静态变量或静态方法的确在当前类或接口中定义时,才可以看作是对类或接口的主动使用;(如用子类引用调用父类静态方法或变量,只会初始化父类)
调用ClassLoader.loadClass()方法加载一个类时,只会加载,但不会初始化;
子类父类初始化过程:
先对这个类进行加载和连接-> 如果有直接父类,先加载连接初始化这个父类->重复以上步骤直到所有父类初始化,初始化当前类;
(先加载连接当前类,再加载连接初始化父类,再初始化当前类)
class Base {
static {
System.out.println("init Base");
}
}
class Sub extends Base {
static {
System.out.println("init Sub");
}
}
public class ATest extends Sub {
static {
System.out.println("init ATest");
}
public static void main(String args[]) {
System.out.println("main methos");
}
}
结果:
init Base
init Sub
init ATest
main methos
三、类加载器
除了Java虚拟机自带的根类加载器以外,其余的类加载器有且只有一个父加载器;
Java虚拟机自带以下几种加载器:
根(Bootstrap)类加载器:没有父类加载器。负责加载虚拟机核心类,sun.boot.class.path路径下类库,java.lang.*; 实现依赖于底层操作系统,没有继承java.lang.ClassLoader;
扩展(Extension)类加载器:父加载器为根加载器;加载java.ext.dirs下的类库 和 JDK目录下jre/lib/ext目录下类库;继承于java.lang.ClassLoader;
系统(System)类加载器:也称应用类加载器,父加载器为扩展类加载器;加载classpath路径下指定的类库;继承于java.lang.ClassLoader,也是自定义加载器的默认父类;
父亲委托机制:
类加载过程中,会先从最顶层加载器(一般是根加载器)开始往下,先判断父类加载器能不能加载,能加载则往下传递返回加载的类;不能加载则继续往下判断,如果都不能加载,则会抛出ClassNotFoundException异常;
加载器之间的父子关系实际上是指加载器对象之间的包装关系,而不是类之间的继承关系;
命名空间:
命名空间由该加载器及所有父加载器所加载的类组成;
唯一性:在同一个命名空间中,不会出现类的完整名字(包名+类名)相同的两个类;
同一命名空间有以下关系:
同一命名空间的类是相互可见的;(可见是指可以直接使用其类名,不可见的类之间可以通过反射来获取类信息);
子加载器的命名空间所含所有父加载器的命名空间,所有子类加载器的类能看见父加载器的类;但父加载器不能看见子加载器的类;
运行时包:
包名相同,且属于同一个类加载器;
同一运行时包的类才能包可见;如用户自己定义了一个java.lang.Spy,并由自己定义的类加载器加载,由于java.lang.Spy和核心类库java.lang.*由不同的类加载器加载,它们不在同一运行时包,Spy不能访问java.lang.*下的包可见类;
用户自定义类加载器:
扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法;
可通过 this.getClass().getClassLoader()获取类对应的加载器
类的卸载:(清除对应类的Class对象 和 类的二进制数据结构)
由Java虚拟自带的三个类加载器加载的类不能卸载;(虚拟机会始终引用这3个类加载器,类加载器中有一个集合,又会一直引用其加载的类的Class对象)
用户自定义的类加载器加载的类可以被卸载;

整理自孙卫琴《Java面象对象编程》
Java类的加载与生命周期的更多相关文章
- jvm系列(一):java类的加载机制
java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...
- JAVA类的加载、连接与初始化
JAVA类的加载.连接与初始化 类的声明周期总共分为5个步骤1.加载2.连接3.初始化4.使用5.卸载 当java程序需要某个类的时候,java虚拟机会确保这个类已经被加载.连接和初始化,而连接这个类 ...
- 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】
目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...
- JVM(1):Java 类的加载机制
原文出处: 纯洁的微笑 java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang. ...
- 透过现象看本质:Java类动态加载和热替换
摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...
- Java类的加载、链接和初始化
一.Java的类加载机制回顾与总结: 我们知道一个Java类要想运行,必须由jvm将其装载到内存中才能运行,装载的目的就是把Java字节代码转换成JVM中的java.lang.Class类的对象.这样 ...
- java 类的加载,链接,初始化
本篇的话题,讨论Java类的加载.链接和初始化.Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象.一个Java类从字节代码 ...
- 【Java基础】Java类的加载和对象创建流程的详细分析
相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下. 实例问题 实例代码 Parent类 package ...
- Java类的加载和对象创建流程的详细分析
相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下: package com.test; public ...
随机推荐
- EasyMvc入门教程-基本控件说明(2)定时器
我们有时候希望系统能自动刷新后台数据或者做某个动作,那么定时器的作用就体现出来了. EasyMvc默认提供的服务器可以定时调前端方法与定时调后端方法,先看例子: 定时调客户端事件 实现代码: @Htm ...
- EasyMvc入门教程-高级控件说明(20)表格控件
表单与表格是信息化系统里很常见的控件,EasyMvc提供了简单的数据绑定方式(基于Json),看下面的示例: 准备的接口地址代码如下:(该接口适用以下所有例子) public IActionResu ...
- ylb:了解存储过程
ylbtech-SQL Server:SQL Server-了解存储过程 了解存储过程 ylb:了解存储过程 返回顶部 存储过程 2.2.1 主要的编程结构: 变量 数据类型 输入/输出变量 返回值 ...
- CityEngine结合ArcGIS制作地质体web场景 [转]
CityEnginewebWebWEB地质体 原文地址:http://www.cnblogs.com/esrichina/archive/2012/11/12/2762163.html 当我们想要对地 ...
- MFC中几个函数的使用
1.GetDlgItem() CWnd* GetDlgItem ( int nID ) const;这个就足够了(在MFC中经常这么用),如果你是在win32API下面写的话,那么一般创建一个窗口 ...
- dynamic_cast<const ObjectList&>(msg);
说简单的就是C里面的强制类型转换,只不过C++里面为了类型安全而这么做的.主要用于 基类与继承类之间. C写多了,类型一般都强转,特别是指针.int * a;void * b = (void*)a;c ...
- pom.xml基础配置
pom.xml基础配置: maven中,最让我迷惑的还是那一堆配置! 就拿这个属性配置来说: 我需要让整个项目统一字符集编码,就需要设定 <project.build.sourceEncodin ...
- hdu2141Can you find it?
给你四个集合.要你从这四个集合中 各取出一个数出来,推断,取出的前三个数的和 是否等于第四个数. 数据比較大.我的做法是将 前两个集合全部数全部和的情况取出来, 然后二分查找第四个集合和第三集合 ...
- 生成二维码(jquery.qrcode.min.js插件)
生成二维码:参看GitHub资源https://github.com/jeromeetienne/jquery-qrcode 直接上代码:(都需要引入jQuery.js 1.引入(jquery.qr ...
- 添加w3c验证图片到网站
1.在http://validator.w3.org/网站验证 2.添加验证通过后的代码至自己的网站 类似<p> <a href="http://validator. ...