刷头条的时候看到了这个:  你做会错的一道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实例的顺序问题的更多相关文章

  1. 模拟jQuery中的ready方法及实现按需加载css,js实例代码

    这篇文章介绍了模拟jQuery中的ready方法及实现按需加载css,js实例代码,有需要的朋友可以参考一下     一.ready函数的实现经常用jQuery类库或其他类库中的ready方法,有时候 ...

  2. Spring源码加载过程图解(一)

    最近看了一下Spring源码加载的简装版本,为了更好的理解,所以在绘图的基础上,进行了一些总结.(图画是为了理解和便于记忆Spring架构) Spring的核心是IOC(控制反转)和AOP(面向切面编 ...

  3. js 利用 ajax 加载 js ,显示加载进度 ,严格按照js的顺序先后加载到页面

    js 利用 ajax 加载 js ,显示加载进度 ,严格按照js的顺序先后加载到页面 , 做手机端开发时,发现一个问题,有些浏览器,在网速比较慢的情况下,js文件没有加载完,后续的调用已经开始调用了, ...

  4. 浏览器加载和渲染html的顺序

    前阵子,在组内给大家做了一次关于“浏览器加载和渲染HTML的顺序”的分享,这里再总结一下吧. AD:干货来了,不要等!WOT2015 北京站演讲PPT开放下载! 1.浏览器加载和渲染html的顺序 浏 ...

  5. Struts2配置拦截器,struts2加载常量时的搜索顺序

    1:struts2加载常量时的搜索顺序 1.Struts-default.xml 2.Struts-plugin.xml 3.Struts.xml 4.Struts-properties(自己创建的) ...

  6. 浏览器加载和渲染html的顺序-css渲染效率的探究

    1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...

  7. 浏览器加载和渲染html的顺序(html/css/js)

    最近在学习前端的技术,把html.js.css的基础知识看了看.感觉越看越觉得前端并不比后端容易,技术含量还是相当大的.今天突然想弄明白浏览器到底是怎么加载和渲染html的?html中的DOM.js文 ...

  8. Javascript中页面加载完成后优先执行顺序

    Javascript中页面加载完成后优先执行顺序 document优先于windowwindow优先于element //document加载完成执行方法体 document.addEventList ...

  9. 浏览器加载和渲染html的顺序-css渲染效率的探究(转载)

    1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...

随机推荐

  1. HHH

    https://data-artisans.com/flink-forward/resources/alibabas-common-algorithm-platform-on-flink https: ...

  2. Machine Learning Library (MLlib) Guide, BOOKS

    download.microsoft.com/download/0/9/6/096170E9-23A2.../9780735698178.pdf   Microsoft Azure Essential ...

  3. SQL Server 2008 R2:error 26 开启远程连接详解

    远程连接sql server 2008 数据库,出现下面的错误: <--在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.    未找到或无法访问服务器.请验证实例名称是 ...

  4. u3d中的INput

    属性 属性: 功能: 轴 (Axes) 包含当前工程的所有定义的输入轴:数目 (Size) 该工程中不同输入轴的数量,元素 0.1.... 是要修改的特定的轴. 名称 (Name) 在游戏启动器中以及 ...

  5. vue2 自定义时间过滤器

    // template {{a | data}} //script data:{   a: Date.now() } filters: {   data:function (input) {

  6. 针对后台TCP服务F5健康检查配置

    1.TCP-HALF-OPEN方式 TCP-HALF-OPEN的探测方式,实际是F5每隔一个固定的时间,发送一个SYN包给资源池pool中的一个member,等待服务器返回SYN_ACK,在收到SYN ...

  7. C++中的new、operator new与placement new

    转:http://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html new/delete与operator new/operator ...

  8. Sphinx/Coreseek 4.1的安装流程

    yum install mysql-devel libxml2-devel expat-devel cd /data/software/ wget http://www.coreseek.cn/upl ...

  9. <孙阿姨炒股记:3500元炒出千万身家的股市智慧 >读书笔记

    书在这里 个人投资者要想在中国股市上生存,并且获利,首先要“胆子小” 国家方针政策要花力气去研究 不要听小道消息,比较天下没有免费的午餐 好公司不一定就能赚钱,好的买点药抓住,好的卖点更要抓住 趋势是 ...

  10. Android 一条竖线或横线、画边框

    Android 一条竖线或横线.画边框 博客分类: android androidshape  1.画线 [img] http://pic002.cnblogs.com/images/2010/122 ...