版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习!

大家都知道Java程序被编译器编译成字节码文件保存在硬盘里,Java虚拟机在执行代码时首先要把编译后的字节码文件从硬盘加载到内存中,然后才能执行。这里所说的加载包括一连串的动作,即虚拟机把字节码文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Class对象,这就是虚拟机的类加载机制。

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载7个阶段。前面5个阶段是类加载的过程,初始化阶段是类加载过程的最后一步,在初始化阶段,会为类的静态变量赋予初始值(声明静态变量时显式赋值,或者在static块中赋值),要注意的是,在准备阶段,虚拟机已经为类的静态变量初始化默认值,而在初始化阶段的赋值是我们程序主观给定的初始值,两者并不冲突。到了初始化阶段,才真正开始执行类中定义的程序代码。

相信很多程序猿都有过这样一个疑问,什么情况下需要开始类加载过程中的第一阶段:加载?(这里加载指的是将类的.class文件中的二进制数据读入到内存中,将其放入到运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构)我同样也被这个问题困扰过,Java虚拟机规范中对何时开始加载并没有进行强制约束,交给虚拟机的具体实现来自由把握。Java语言在运行期间是动态加载的,在第一次需要使用类信息时会进行加载。比如:调用静态成员变量或方法、实例化一个对象、加载子类时会先加载父类。

但是对于初始化阶段,虚拟机规范则严格的规定了有且只有在对类首次主动使用时,才执行初始化操作(加载、验证、准备阶段在此之前进行)。

Java程序对类的使用方式分为两种:主动使用和被动使用。所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化这个类,否则不执行初始化阶段操作。
       什么是对类的主动使用和被动使用?在Java程序中,一共有6种情况会被称为对类的主动使用,除了这6种,其他所有的对类的使用方式都被称为被动使用。当这6种方式出现时如果类没有进行过初始化,则会触发其进行初始化。

主动使用(6种):

       1、创建类的实例

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

       3、调用某个类的静态方法

       4、反射(Class.forName("java.lang.String"))

       5、初始化一个类的子类

       6、Java虚拟机启动时被标明为启动类的类

       前3种情况很好理解,第4种运用反射返回一个Class对象,这时与Class对象相关联的类会被初始化。第5种初始化一个类的子类是指,给子类的静态变量赋予初始值,这时父类会先进行初始化。第6种当一个类被标明为启动类,例如一个类中含有main方法,这个类就是启动类,Java虚拟机启动时会加载并初始化这个类。

这里再强调一遍,除了以上6种情况,其他所有对类的操作都不会触发虚拟机对类进行初始化操作,即在类加载过程中不会执行初始化这一阶段。

ClassLoader机制:一个类何时会被虚拟机初始化?的更多相关文章

  1. 2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。

    需求:我们的需求是,在spring初始化完毕时,使我们自定义一个类Bird类可以得到spring容器内容. 实现步骤: 1.首先我们来看一下ApplicationContextAwareProcess ...

  2. java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。

    首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一.  类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...

  3. Java反射机制demo(六)—获得并操作一个类的属性

    Java反射机制demo(六)—获得并操作一个类的属性 获得并操作一个类的属性?! 不可思议啊,一个类的属性一般都是私有成员变量啊,private修饰符啊! 但是毫无疑问,这些东西在Java的反射机制 ...

  4. Java反射机制demo(五)—获得并调用一个类中的方法

    Java反射机制demo(五)—获得并调用一个类中的方法 这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和 ...

  5. Java反射机制demo(四)—获取一个类的父类和实现的接口

    Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 ...

  6. C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西付给另一个类对象,而不是付给引用地址)

    from:https://blog.csdn.net/poxiaohai2011/article/details/27555951 //C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西 ...

  7. Qt信号槽机制的实现(面试的感悟,猜测每一个类保存的一个信号和槽的二维表,实际使用函数指针 元对象 还有类型安全的检查设定等等)

    因为面试时问了我这道题,导致我想去了解信号槽到底是如何实现的,于是贴着顺序看了下源码,大致了解了整个框架.网上关于信号槽的文章也很多,但是大部分都是将如何应用的,这里我就写一下我所理解的如何实现吧, ...

  8. 深度分析 Java 的 ClassLoader 机制(源码级别)

    写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...

  9. 深度分析Java的ClassLoader机制(源码级别)

    写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...

随机推荐

  1. 页面性能优化的利器 — Timeline

    欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 陈泽钦,腾讯移动客户端工程师,目前就职于腾讯MIG移动互联网事业群,负责腾讯浏览服务TBS的X5内核业务. 1 ...

  2. Linux centos7下安装配置redis及Redis desktop Manager工具连接注意事项

    基本工具:VMware12.CentOS-7-x86_64-Everything-1611.iso.redis-desktop-manager-0.8.0.3841 废话不多说,首先,关于什么是Red ...

  3. Charles抓取https请求详解

    大家好,我是TT,互联网测试行业多年,没有牛逼的背景,也没有什么可炫耀的,唯独比他人更努力,在职场打拼.遇到过的坑,走过的弯路,愿意与大家分享,分享自己的经验,少走弯路.首发于个人公众号[测试架构师] ...

  4. java:Comparator比较器

    /*Comparator是java.util包里的一个接口,使用时应该实现导入相应的包, *再写一个实现了Comparator接口的类,并复写int compare(Object o)方法, *写出你 ...

  5. Linux实战教学笔记11:linux定时任务

    第十一节 linux定时任务 标签(空格分隔): Linux实战教学笔记 ---更多资料点我查看 1.1 定时任务Crond介绍 Crond是linux系统中用来定期执行命令/脚本或指定程序任务的一种 ...

  6. 如何将angular-ui的图片轮播组件封装成一个指令

    在项目开发中我们经常会遇到图片轮播的功能点: 如果我们开发人员自己原生手写,将会花费很多的时间,最终得不偿失. 接下来就详细说说如何使用angular-ui发热图片轮播模块,并且将它写成一个指令(便于 ...

  7. js实用方法记录-简单cookie操作

    js实用方法记录-简单cookie操作 设置cookie:setCookie(名称,值,保存时间,保存域); 获取cookie:setCookie(名称); 移除cookie:setCookie(名称 ...

  8. Go - Struct

    定义 go 语言中的struct与c的很相似,此外,go没有Class,也没有继承. stuct的格式为:type <name> struct{} package main import ...

  9. 019 关联映射文件中集合标签中的lazy(懒加载)属性

    <set>.<list>集合上,可以取值:true/false/extra,(默认值为:true) 实例一:(集合上的lazy=true(默认))class默认lazy=tru ...

  10. Java如何转换protobuf-net中的bcl.DateTime对象

    一.定义DateTime Message 参考文档:https://github.com/mgravell/protobuf-net/blob/master/src/Tools/bcl.proto m ...