笔者将通过本文向大家介绍一下Java中的类加载顺序,既然是一门编程语言,那么纯说理论是不行的,应该通过实践来验证理论,理论来指导实践。下面笔者就来写一个验证类加载优先级的Java demo供大家学习和参考。
/**
*
* @author Liangyj
*加载优先级:1.静态变量和静态代码块(类加载时执行,只加载一次并且常驻内存)、静态方法(只加载一次并且常驻内存,直接使用类名调用时才执行)
*-->2.构造代码块(创建对象时执行)-->3.构造方法(创建对象时执行)-->4.普通方法(创建对象并调用时执行)
*/
public class TestJava {
public static void main(String[] args) {
System.out.println("我是main方法A:"+A+",B:"+B);
}
//构造方法
public TestJava(){
B = 10;
A = 4;
System.out.println("我是构造方法A:"+A+",B:"+B);
}
//构造代码块
{
A = 3 ;
B = 3;
System.out.println("我是构造代码块!A:"+A);
}
//静态变量
private static int B = 1;
//静态代码块
static {
A = 2 ;
B = 2;
System.out.println("我是静态代码块:"+"B:"+B);
}
//静态变量
private static int A = 1;
}
class RunTest{
@SuppressWarnings("static-access")
public static void main(String[] args) {
TestJava testJava = new TestJava();
testJava.main(args);
}
}
下面是控制台输出结果:
我是静态代码块:B:2
我是构造代码块!A:3
我是构造方法A:4,B:10
我是main方法A:4,B:10
偶然间笔者在网上看到有人写了关于类加载顺序的文章,并贴出了Java demo,最后得出了加载顺序的结论。但是笔者发现文章的作者写的代码并不严谨,得出的结论并不完全正确。因为光看在控制台输出的顺序,并不能完全说明Java的类加载顺序。比如,在加载优先级为同级时,加载和输出结果的顺序是根据代码的上下文顺序来决定的,这并不能说明优先级的高低。所以笔者在这里加以说明,以此做个提醒。笔者在代码中特意将优先级高的放在比它优先级低的代码后面,以此更为直观的证明它的优先级更高,而不是因为代码顺序导致。本Java demo纯属笔者原创,根据自己思路所写。为了方便大家代码阅读,笔者将RunTest类和TestJava类放在同一个.java文件中(为新手朋友稍作解释,老手无视即可)。
年后回来有个小伙伴问了我个问题(如果你是一个细心的、爱思考的读者,相信你也会发现这个问题,但是并没有读者在笔者的博文下留言提问,笔者有点小小的失落,不知大家是浅尝辄止没有注意到,还是自己知道其中的道理,好了,言归正传),正好适合放在这里做引申:
1.声明与赋值的关系(或顺序)
2.初始化加载和创建对象时加载,以及方法调用时加载
先对第一点作出解释:在上面的代码中静态变量A,似乎是先被静态代码块赋值了,再声明的变量类型,为何该代码能通过编译呢?其实不然,虽然在上面我们已经得出了类的加载顺序,静态变量和静态代码块的优先级是相同的,此时根据代码顺序加载,但是变量(属性)的声明是先于赋值的,这是由类加载机制决定的,类的加载机制可参考:
http://blog.csdn.net/boyupeng/article/details/47951037。
再解释第二点:静态变量、静态代码块、静态方法是在类被加载时就初始化加载,但静态方法作为一个函数(方法)不会直接执行,同样需要被调用才执行,只不过不需要创建一个新的对象,因为它是先于对象存在的,而构造代码块和构造函数(方法)是在创建对象时加载,普通方法在被调用时才加载。
另外注意:静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问。结合笔者给的demo,在上述代码中,静态代码块中给A赋值(A = 2)是可以编译通过的,而如果要引用变量A(例如输出语句改为打印A的值)则会报错:不能在定义字段之前引用字段(报错信息的中文翻译)。 --2017/2/3引申补充
原文永久地址:
http://jsonliangyoujun.iteye.com/blog/2348180
分享到:
相关推荐
springboot入门实例2:springboot配置文件的位置和加载优先级 博客地址:https://blog.csdn.net/u010476739/article/details/98380095
类的生命周期包含了如上的7个阶段,其中 验证 、 准备 、 解析 统称为 连接,类的加载主要是前五个阶段,每个阶段基本上保持如上顺序 开始(仅仅是开始,实际上执行是交叉混合的),只有 解析 阶段不一定...
Unity简单实现资源管理类,使用协程加载加载AssetBundle,支持优先级队列,尽量考虑加载新能。
ETL流程是一个以数据为中心的工作流,对ETL工作流的执行过程进行论述,提出了一个算法,计算ETL工作流中各个活动的执行优先级,在工作流执行中为优先级相同且相互之间没有依赖关系的活动集创建多个线程,通过并行...
NULL 博文链接:https://xiaoxinshome.iteye.com/blog/1688607
将应用部署在weblogic中于axis2冲突的问题及解决方案
使用!important可以改变优先级别为最高,其次是style对象,然后是id class tag ,另外,另外在同级样式按照申明的顺序后出现的样式具有高优先级。感兴趣的朋友可以了解下
NULL 博文链接:https://as3.iteye.com/blog/1135300
驱动加载工具是一款用于驱动安装、卸载的小软件,驱动加载工具可以帮助您方便的把驱动程序安装上或卸载掉,并支持拖拽获取文件路径功能。需要的朋友们可以前来下载使用。... 六、提升程序自身的权限和优先级。 压缩包中
软件名称:驱动加载工具(InstDrv - 中文版) 软件版本:V1.3版 软件类型:个人免费版(无插件) 运行环境:Windows操作系统 开发作者:Coderui 更新日期:2008年04月18日 联系邮箱:coderui@163.com 作者博客:...
复制代码代码如下: { height: 100%; width: 200; position: absolute; left: 0; border: solid 2 #EEE; } .current_block { ...1. 样式表的元素选择器选择越精确,则其中的样式优先级越高: id选择器指定的样式 > 类选
JVM被分为三个主要的子系统:类加载器子系统、运行时数据区、执行引擎Java的动态类加载功能是由类...这个加载器会被赋予最高优先级扩展类加载器–负责加载ext目录(jre\lib)内的类应用程序类加载器–负责加载应用程序级
listview/gridview加载显示大量图片,对内存和性能都...3. 调整Load线程优先级为Thread.NORM_PRIORITY-1,不要和UI线程抢时间片,使滚动更流畅。 该代码用listview作为示范,但是里面用到的技术完全可以用于gridview。
图片缓存工程、可以实现图片异步下载、可设置内存缓存、磁盘缓存,并可设置下载优先级,等各种你想要的大部分功能需求.zip,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
使用IntersectionObserver API,优先级提示和动画对惰性加载图像进行智能React 特征 通过仅加载折页上方的图像来加快初始页面加载 响应占位符和动画 具有重要性属性的支持 使用智能下载逻辑 用法简单,体积小,包括...
本文主要介绍 preload 的使用,以及与 prefetch 的区别。然后会聊聊浏览器的加载优先级,大家一定要认真看完
1 静态变量,静态代码块(类加载时执行,类不加载不执行) 2 实例变量,实例代码块(创建对象时才执行,不创建对象不执行) 3 构造函数,(创建对象时执行完2后再执行构造函数,不管构造函数是public还是private...
基于ES6装饰器+类的路由器,支持继承,覆盖,优先级,自动加载控制器等。 在引擎盖下使用 。 安装 npm i koa-dec-router 要么 yarn add koa-dec-router 演示版 app.js import Koa from 'koa' import DecRouter ...
先根据where 约束条件 将数据从表中加载到内存,所以where的条件作用在数据之前,然后根据字段进行分组,在内存中形成一张虚拟的表包含字段, 如果此时有聚合函数则先执行聚合函数,并将聚合函数字段也加到虚拟的表...