介绍

一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段:

加载

主要是:把类的信息加载到方法区中,并在堆中实例化一个Class对象。

加载方式

根据类的全路径加载class文件

从jar的包中读取class文件

根据一定的规则实时生成,比如设计模式中的动态代理模式,就是根据相应的类自动生成它的代理类。

加载的时期

不是jvm启动就加载,而是在真是使用的时候才会触发加载。

  • new 一个类的时候
  • 调用类的静态方法,以及读取或者修改一个类的静态字段的时候(不是常量)
  • 这个类是程序的入口类
  • 对这个类进行反射的时候(执行了上面的行为)

连接

一般会跟加载阶段和初始化阶段交叉进行。

验证

验证一下这个类是否合法,

  • 字节码格式是否合法
  • 变量和方法是否有重复
  • 继承和实现是否符合标准

    。。。

准备

给类的静态变量分配并初始化存储空间;

也就是给静态变量赋默认的初始值(不包括非静态变量)

解析

把符合引用转换为直接引用。

比如我们要在内存中找一个类里面的一个叫做show的方法,显然是找不到。但是在解析阶段,

jvm就会把show这个名字转换为指向方法区的的一块内存地址,比如c17164,通过c17164就可以找到show这个方法具体分配在内存的哪一个区域了。

这里show就是符号引用,而c17164就是直接引用。

在解析阶段jvm会将所有的类或接口名、字段名、方法名转换为具体的内存地址。

初始化

执行静态变量的初始化和静态Java代码块,并初始化程序员设置的变量值!

时机

和加载的时机一样,更准确的说初始化之前必须先经过加载,所以他们基本一样

  • new 一个类的时候
  • 调用类的静态方法,以及读取或者修改一个类的静态字段的时候(不是常量)
  • 对这个类进行反射的时候(执行了上面的行为)
  • 初始化一个类的子类,该子类所有的父类都会被初始化。
  • 作为程序的入口类(如:main方法所在的类,java 命令跟着的类)

过程

按照顺序自上而下运行类中的【变量赋值语句】和【静态语句】,

如果有父类,则首先按照顺序运行父类中的变量赋值语句和静态语句。

使用

使用阶段包括主动引用和被动引用。

主动引用(会引起类的初始化)

  • new 一个类的时候
  • 调用类的静态方法,以及读取或者修改一个类的静态字段的时候(不是常量)
  • 这个类是程序的入口类
  • 对这个类进行反射的时候(执行了上面的行为)

注意:以上几种主动引用会引起类的初始化,这里的几种情况只有new或者使用class.newInstance()才会调用构造函数!

被动引用(不会引起类的初始化)

引用父类的静态字段

定义类数组

引用类的常量

例如

public class TestClassInit {
static {
System.out.println("初始化InitClass");
}
public static String staticA = null;
public final static String finalB = "b";
public static void staticMethod(){}
}
public class Test {
public static void main(String args []){
//主动引用
//new 一个类的时候
TestClassInit tct=new TestClassInit();
//读取静态变量
String staticA=TestClassInit.staticA;
//设置静态变量
TestClassInit.staticA="A";
//调用静态方法
TestClassInit.staticMethod(); //被动引用
//定义类数组,不会引起类的初始化
TestClassInit[] tcts=new TestClassInit[10];
//引用类的常量,不会引起类的初始化
String finalB=TestClassInit.finalB;
}
}

卸载

满足下面请看才会卸载类:

  • java堆中不存在该类的任何实例。
  • 加载该类的ClassLoader已经被回收
  • 该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法

相关问题

Class.forName()和ClassLoader.loadClass的区别

Class.forName(className)方法,内部实际调用的方法是 Class.forName(className,true,classloader);

第2个boolean参数表示类是否需要初始化, Class.forName(className)默认是需要初始化。

一旦初始化,就会触发目标对象的 static块代码执行,static参数也也会被再次初始化。

ClassLoader.loadClass(className)方法,内部实际调用的方法是 ClassLoader.loadClass(className,false);

第2个 boolean参数,表示目标对象是否进行链接,false表示不进行链接,由上面介绍可以,

不进行链接意味着不进行包括初始化等一些列步骤,那么静态块和静态对象就不会得到执行;

如:Student.class.getClassLoader().loadClass("com.we.web.erp.jvm.Student");

Class.forName("com.we.web.erp.jvm.Student");

静态代码块,构造代码块,构造函数,以及静态变量赋值, 实例变量赋值 的执行顺序;

  • 没有继承关系的情况下:

    静态变量赋值 > 静态代码 > 实例变量赋值 > 构造代码 > 构造函数
public class School {

    public School(){
System.out.println("School的构造函数执行[静态属性]!");
}
} public class Student {
public Student(){
System.out.println("Student类的构造函数执行[非静态属性]!");
}
} public class SubClass {
private Student student=new Student();
private static School school=new School();
static
{
System.out.println("静态代码块!");
} {
System.out.println("构造代码块!");
} public SubClass()
{
System.out.println("构造函数!");
}
}

执行结果:

School的构造函数执行[静态属性]!
静态代码块!
Student类的构造函数执行[非静态属性]!
构造代码块!
构造函数!

执行这里的静态变量赋值和实例变量赋值可以按照下图理解;

  • 有继承的情况下
public class SubClass extends SuperClass {
private Student student=new Student();
private static School school=new School();
static
{
System.out.println("子类静态代码块!");
} {
System.out.println("子类的构造代码块!");
} public SubClass()
{
System.out.println("子类构造函数!");
}
} public class SuperClass {
static {
System.out.println("父类静态代码块!");
}
{
System.out.println("父类的构造代码块!");
}
SuperClass()
{
System.out.println("父类的构造函数!");
} }

执行结果:

父类静态代码块!
School的构造函数执行[静态属性]!
子类静态代码块!
父类的构造代码块!
父类的构造函数!
Student类的构造函数执行[非静态属性]!
子类的构造代码块!
子类构造函数!

简述JAVA类的生命周期的更多相关文章

  1. Java类的生命周期详解

    引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告 ...

  2. 【转】Java 类的生命周期详解

    一. 引 言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大 ...

  3. 【转载】详解java类的生命周期

    原文地址:http://blog.csdn.net/zhengzhb/article/details/7517213 引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑, ...

  4. [Java]类的生命周期(上)类的加载和连接[转]

    本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 类加载器,顾名思义,类加载器(class loader)用来加载 Java 类到 Java ...

  5. JVM类加载器及Java类的生命周期

    预定义类加载器(三种): 启动(Bootstrap)类加载器: 是用本地代码实现的类装入器,它负责将<Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar) ...

  6. JVM-类加载过程(Java类的生命周期)

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

  7. Java类的生命周期(转)

    引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告 ...

  8. 详解Java类的生命周期

    引言 最近有位细心的朋友在阅读笔者的文章时,对Java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内Java方面的教材大多只是告 ...

  9. Java类的生命周期浅析

    类的生命周期?对象的生命周期?Spring bean 的生命周期?很多同学可能在学习java基础知识之初,很容易把这几个搞混.本文先来说说Java类的生命周期. 目录 知识前提 类的生命周期 加载(L ...

随机推荐

  1. C#学习基础资料记录---字典(Dictionary),时间表示方法(DateTime.Now),文件操作

    1.字典 https://www.cnblogs.com/gengaixue/p/4002244.html 2.时间的表示方法 DateTime.Now的多种用法 https://www.cnblog ...

  2. Linux I2C核心、总线和设备驱动

    目录 更新记录 一.Linux I2C 体系结构 1.1 Linux I2C 体系结构的组成部分 1.2 内核源码文件 1.3 重要的数据结构 二.Linux I2C 核心 2.1 流程 2.2 主要 ...

  3. arcgis js之点击获取featureLayer中的点

    arcgis js之点击获取featureLayer中的点 代码: this.view.on('click', (evt) => { let layer = this.map.findLayer ...

  4. JS 实现继承的方法 ES6 and ES5

    继承 ES6 方法  (类的继承) ES6中有一个属性的 extends 语法: ​ • class Father {} ​ • class Son extends Father{} ​ 注意:是子类 ...

  5. 开源跨境ERP - 小老板 Docker/Docker Compose一键部署

    先上部署成功后的截图,各个菜单点击均无报错 DockerCompose 包含: 1. 三个mysql5.7数据库 2. redis php会话存储+ memcached 3. 小老板php主程序 do ...

  6. vue项目js实现图片放大镜功能

    效果图:   我写的是vue的组件形式,方便复用,图片的宽高,缩放的比例可以自己定义 magnifier.vue <template> <div class="magnif ...

  7. 分布式任务队列 Celery —— Task对象

    转载至 JmilkFan_范桂飓:http://blog.csdn.net/jmilk  目录 目录 前文列表 前言 Task 的实例化 任务的名字 任务的绑定 任务的重试 任务的请求上下文 任务的继 ...

  8. Django—logging日志

    简介 Django使用python自带的logging 作为日志打印工具.简单介绍下logging. logging 是线程安全的,其主要由4部分组成: Logger 用户使用的直接接口,将日志传递给 ...

  9. 10_Hive自定义函数UDF

    Hive官方的UDF手册地址是:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF 1.使用内置函数的快捷方法: 创 ...

  10. 修改office2019安装位置,自定义安装需要的功能

    更新:2019.5.30楼主本人本次重装系统后装office2019再次测试,没有任何问题,没认真看文章,自己胡乱一同操作,导致各种问题的,出了错就就瞎评论,说博主误导人,对你们这种人就是呵呵.左转不 ...