一、概要:

类的生命周期从类的 加载、连接、初始化 开始,到类的 卸载结束;

二、几个阶段:

加载:查找并加载类的二进制数据。(把类的.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类的加载与生命周期的更多相关文章

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

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

  2. JAVA类的加载、连接与初始化

    JAVA类的加载.连接与初始化 类的声明周期总共分为5个步骤1.加载2.连接3.初始化4.使用5.卸载 当java程序需要某个类的时候,java虚拟机会确保这个类已经被加载.连接和初始化,而连接这个类 ...

  3. 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】

    目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...

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

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

  5. 透过现象看本质:Java类动态加载和热替换

    摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...

  6. Java类的加载、链接和初始化

    一.Java的类加载机制回顾与总结: 我们知道一个Java类要想运行,必须由jvm将其装载到内存中才能运行,装载的目的就是把Java字节代码转换成JVM中的java.lang.Class类的对象.这样 ...

  7. java 类的加载,链接,初始化

    本篇的话题,讨论Java类的加载.链接和初始化.Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象.一个Java类从字节代码 ...

  8. 【Java基础】Java类的加载和对象创建流程的详细分析

    相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下. 实例问题 实例代码 Parent类 package ...

  9. Java类的加载和对象创建流程的详细分析

    相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下: package com.test; public ...

随机推荐

  1. php 列出当前目录

    $path="."; //初使化用户所操作目录 $prevpath=dirname($path); //初使化当前脚本所在目录 $dir_handle=opendir($path) ...

  2. GridView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL)不兼容低版本号系统解决方式

    项目开发中须要使用GridView批处理操作,多项选择. 可是GridView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL)不兼容低版本号. 找 ...

  3. EclipseADT(4.2) 安装 STS(spring )

    因为ADT 版本是4.2, 网上找了一圈 from: https://spring.io/blog/2012/03/14/early-access-springsource-tool-suite-fo ...

  4. 微信小程序 - 时间戳转时间

    获取当前时间:十位unix时间戳 var timestamps = Math.round(new Date().getTime() / 1000).toString(); 时间戳转时间(官方自带) 使 ...

  5. jquery ajax传参数问题

    var fd = new FormData();//实例化表单,提交数据使用fd.append('imgUrl',imgUrl);//将files追加进去fd.append('typeId',type ...

  6. 常见的CPU訪问引起的内存保护问题为什么仅仅用event_122上报 - 举例2

    还有一个样例.通过以下的log看,CPU在訪问reserved的地址0x53611EFD.非法訪问时该地址会在L1D内存控制器的L1DMPFSR寄存器中记录. ** FATAL EXCEPTION N ...

  7. caffe2--------ImportError: No module named past.builtins

    whale@sea:~/anaconda2/lib/python2.7/site-packages$ python Python 2.7.14 |Anaconda custom (64-bit)| ( ...

  8. debian jessie install note

    Debian支持非常多的硬件,包括arm/mips/ppc/x86,于是想安装个Debian看看,也不想总屈服在canonical的ubuntu下面. 光盘镜像太多了 纯社区版的安装总是没有想像得那么 ...

  9. uboot之bootm以及go命令的实现

    本文档简单介绍了uboot中用于引导内核的命令bootm的实现,同时分析了uImage文件的格式,还简单看了一下uboot下go命令的实现 作者: 彭东林 邮箱: pengdonglin137@163 ...

  10. Win7获取管理权限修改Host文件以其他权限问题

    ——win7管理员权限修改Host文件——百度经验 win7管理员权限获取办法: win7管理员权限 获取办法——经验——百度 win7最高权限获取: win7最高权限 获取——百度经验