ClassLoader机制:一个类何时会被虚拟机初始化?
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习!
大家都知道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机制:一个类何时会被虚拟机初始化?的更多相关文章
- 2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。
需求:我们的需求是,在spring初始化完毕时,使我们自定义一个类Bird类可以得到spring容器内容. 实现步骤: 1.首先我们来看一下ApplicationContextAwareProcess ...
- java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。
首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一. 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...
- Java反射机制demo(六)—获得并操作一个类的属性
Java反射机制demo(六)—获得并操作一个类的属性 获得并操作一个类的属性?! 不可思议啊,一个类的属性一般都是私有成员变量啊,private修饰符啊! 但是毫无疑问,这些东西在Java的反射机制 ...
- Java反射机制demo(五)—获得并调用一个类中的方法
Java反射机制demo(五)—获得并调用一个类中的方法 这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和 ...
- Java反射机制demo(四)—获取一个类的父类和实现的接口
Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 ...
- C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西付给另一个类对象,而不是付给引用地址)
from:https://blog.csdn.net/poxiaohai2011/article/details/27555951 //C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西 ...
- Qt信号槽机制的实现(面试的感悟,猜测每一个类保存的一个信号和槽的二维表,实际使用函数指针 元对象 还有类型安全的检查设定等等)
因为面试时问了我这道题,导致我想去了解信号槽到底是如何实现的,于是贴着顺序看了下源码,大致了解了整个框架.网上关于信号槽的文章也很多,但是大部分都是将如何应用的,这里我就写一下我所理解的如何实现吧, ...
- 深度分析 Java 的 ClassLoader 机制(源码级别)
写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...
- 深度分析Java的ClassLoader机制(源码级别)
写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...
随机推荐
- 蓝桥杯-四平方和-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- cmd 命令行模式操作数据库 添加查询 修改 删除 ( 表 字段 数据)
一 查看数据库.表.数据字段.数据 1 首先配置环境变量 进入mysql 或者通过一键集成工具 打开mysql命令行 或者mysql 可视化工具 打开命令行 进入这样的界面 不同的机器操作不同 ...
- ThinkPHP框架的增删改
使用TP框架主要是比较简单一些,之前我们写增删改,代码量相对来说还是比较多的,这里利用tp框架写起来是非常简单的,大大的减少了代码量 这里我是以数据库的nation表为例的,nation表 ...
- 在Mvc中进行异步请求是出现(没有为该对象定义无参数的构造函数)
解决办法就是给相应的类添加无参数的构造函数:
- Spring boot 默认静态资源路径与手动配置访问路径
在application.propertis中配置 ##端口号server.port=8081 ##默认前缀spring.mvc.view.prefix=/## 响应页面默认后缀spring.mvc. ...
- NSLog (Log信息的输出)
概述 NSLog是 cocoa的框架中提供的一个方法 NSLog的定义 NSLog定义在NSObjCRuntime.h中 NSLog与printf的差异 1)NSLog传递进去的格式化字符是NSStr ...
- 关于使用命令添加jar进自己的pom文件中-maven项目添加jar包
现在几乎开发项目都是使用的maven项目,但是有的时候可以使用比较偏门或者新的jar可能在网上搜不到在pom文件里的配置应该如何写,因此写下这篇博客. 比如我现在想加入的AAA.jar这个包 打开cm ...
- Adline网络的LMS算法与梯度下降
LMS算法,即为最小均方差,求的是误差的平方和最小. 利用梯度下降,所谓的梯度下降,本质上就是利用导数的性质来求极值点的位置,导数在这个的附近,一边是大于零,一边又是小于零的,如此而已... 而这个里 ...
- 转:Redis使用认证密码登录
Redis默认配置是不需要密码认证的,也就是说只要连接的Redis服务器的host和port正确,就可以连接使用.这在安全性上会有一定的问题,所以需要启用Redis的认证密码,增加Redis服务器的安 ...
- Linux增加磁盘操作
首先,增加磁盘分为4个大步骤:1.插上硬盘:2.分区;3.格式化4.挂载,然后分别说说以上四步的具体事项和注意内容. 1.插上硬盘(本位以虚拟机为例) 新买来一块磁盘,把磁盘插到主板上.虚拟机中操作如 ...