字节码加载和class实例的顺序问题
刷头条的时候看到了这个: 你做会错的一道Java面试题:字节码加载和class实例的顺序问题
以前也看到过,应该是阿里的校招笔试题,当时懒得理这种工作中毫无意义的东西。
今天突然来了兴趣,就想看看能不能靠自己的知识来理清其中的逻辑,结果还不错,(*^_^*)。
原题略绕,不直观,先来个精简版:
public class A {
static{
System.out.println("我是静态代码块");
}
{
System.out.println("实例代码块");
}
public A(){
System.out.println("构造方法");
}
public static void main(String[] args){
new A(); //放开注释,执行,看一下实例代码块和构造方法的执行顺序
}
}
上面的代码,直接执行,即可观察到创建实例时的加载执行顺序。
执行结果如下:
我是静态代码块
实例代码块
构造方法
很明显,一般情况下,创建实例的执行顺序就是:静态代码块 > 实例代码块 > 构造方法。
不知道你们有没有考虑过,为什么要按照这种顺序来?
其实很简单,要满足依赖前置条件!
第一点:因为静态变量的可以被直接调用,所以静态变量部分必须先加载并创建;
第二点:因为静态代码块是在所有静态变量加载完毕后一次性执行的,所以其执行要晚于所有静态变量的加载;
第三点:实例代码块是在创建实例的时候执行的,确切的说,是在实例的内存空间分配完毕,而在构造进行之前执行的。-- 如果学过C++,你应该知道这个。
OK,已经有了上面三点,那我们再来推一下该面试题中的情况。
还是先用简化版本,方便看懂:
public class A {
private static A a = new A(); //静态实例变量
static{
System.out.println("我是静态代码块");
}
{
System.out.println("实例代码块");
}
public A(){
System.out.println("构造方法");
}
//TODO 执行空的main方法,就是只加载字节码。可以有效测试加载过程中的顺序。
public static void main(String[] args){
// new A(); //放开注释,执行,看一下实例代码块和构造方法的执行顺序
}
}
相对于前面那一版,这里只增加了一个本类的静态实例变量 a 。当然还注释掉了main方法中的 new A(),因为我们不需要额外的实例创建来干扰观察。
执行main方法,结果如下:
实例代码块
构造方法
我是静态代码块
用上面三条依赖前置条件推理一下看看:
①先创建静态实例变量,结果执行new A();②而创建实例必然导致实例代码块的先执行,再执行构造代码块!
③执行完构造代码块,静态实例变量a就构造完毕,此时所有静态变量构建完毕,于是执行静态代码块!
原文中有多个静态变量、静态实例变量,静态实例变量的创建还会修改静态变量,让推理每一步静态变量的值。
其实再加上一条即可推理出来:按照声明顺序加载。
总之,虽然知道了原理,但是很烦这种推理题 - 把人搞得晕晕的。
字节码加载和class实例的顺序问题的更多相关文章
- 模拟jQuery中的ready方法及实现按需加载css,js实例代码
这篇文章介绍了模拟jQuery中的ready方法及实现按需加载css,js实例代码,有需要的朋友可以参考一下 一.ready函数的实现经常用jQuery类库或其他类库中的ready方法,有时候 ...
- Spring源码加载过程图解(一)
最近看了一下Spring源码加载的简装版本,为了更好的理解,所以在绘图的基础上,进行了一些总结.(图画是为了理解和便于记忆Spring架构) Spring的核心是IOC(控制反转)和AOP(面向切面编 ...
- js 利用 ajax 加载 js ,显示加载进度 ,严格按照js的顺序先后加载到页面
js 利用 ajax 加载 js ,显示加载进度 ,严格按照js的顺序先后加载到页面 , 做手机端开发时,发现一个问题,有些浏览器,在网速比较慢的情况下,js文件没有加载完,后续的调用已经开始调用了, ...
- 浏览器加载和渲染html的顺序
前阵子,在组内给大家做了一次关于“浏览器加载和渲染HTML的顺序”的分享,这里再总结一下吧. AD:干货来了,不要等!WOT2015 北京站演讲PPT开放下载! 1.浏览器加载和渲染html的顺序 浏 ...
- Struts2配置拦截器,struts2加载常量时的搜索顺序
1:struts2加载常量时的搜索顺序 1.Struts-default.xml 2.Struts-plugin.xml 3.Struts.xml 4.Struts-properties(自己创建的) ...
- 浏览器加载和渲染html的顺序-css渲染效率的探究
1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...
- 浏览器加载和渲染html的顺序(html/css/js)
最近在学习前端的技术,把html.js.css的基础知识看了看.感觉越看越觉得前端并不比后端容易,技术含量还是相当大的.今天突然想弄明白浏览器到底是怎么加载和渲染html的?html中的DOM.js文 ...
- Javascript中页面加载完成后优先执行顺序
Javascript中页面加载完成后优先执行顺序 document优先于windowwindow优先于element //document加载完成执行方法体 document.addEventList ...
- 浏览器加载和渲染html的顺序-css渲染效率的探究(转载)
1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...
随机推荐
- 支付宝对账单下载Java正式商户调用
package code; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; impo ...
- iOS-图片浏览器
// // ViewController.m // 19-图片浏览器 // // Created by hongqiangli on 2017/7/31. // Copyright © 201 ...
- 【工具】我的Eclipse使用习惯
查看代码结构 查看类的层级结构,可用选中类名,按F4,可查看: 类的层级结构: 类的上级结构: 类的下级结构: 安装反编译工具Eclipse Class Decompiler 在Eclipse Mar ...
- Android Manifest <meta-data>
在接入第三方渠道SDK的时候,经常会看到其配置文件AndroidManifest.xml有类似如下的定义: <!-- appid --> <meta-data android:nam ...
- NGUI制作字体的三种方法
主要参考两篇博文: (1).NGUI制作字体的三种方法 (2).使用位图字体工具BMFont从图片生成自定义字体 1.BMFont下载地址 http://www.angelcode.com/produ ...
- 玩转Bootstrap(JS插件篇)-第1章 模态弹出框 :1-4 模态弹出框--结构分析
模态弹出框--结构分析 Bootstrap框架中的模态弹出框,分别运用了“modal”.“modal-dialog”和“modal-content”样式,而弹出窗真正的内容都放置在“modal-con ...
- pandas入门——loc与iloc函数
oc与iloc函数 loc函数 import pandas as pd import numpy # 导入数据 df = pd.read_csv(filepath_or_buffer="D: ...
- Android实例-获取屏幕的物理分辨率
相关资料: http://blog.qdac.cc/?p=1161 实例代码: unit Unit1; interface uses System.SysUtils, System.Types, Sy ...
- JAVA-JSP内置对象之response对象实现页面自动刷新
相关资料:<21天学通Java Web开发> response对象 实现页面自动刷新1.可以通过response对象的addIntHeader()方法添加一个标题为Refrsh的标头,并指 ...
- 算法篇---java经典问题!!!
问题一:==与equal的区别? ==和 equals 都是比较的,而前者是运算符,后者则是一个方法,基本数据类型和引用数据类型都可以使用运算符==,而只有引用类型数据才可以使用 equals,下面具 ...