字节码加载和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.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...
随机推荐
- VS注释与取消注释快捷键
最近在使用VS2010开发ASP.Net,突然发现想全部注释时找不到注释的快捷键,网上查了下,原来很简单,只是需要使用组合键. 注释: 先CTRL+K,然后CTRL+C 取消注释: 先C ...
- openfire聊天记录插件
package com.sqj.openfire.chat.logs; import java.io.File; import java.util.Date; import java.util.Lis ...
- HTTP Basic Authentication认证
http://smalltalllong.iteye.com/blog/912046 ******************************************** 什么是HTTP Basi ...
- 10款jQuery图片左右滚动插件
在现代的网页设计中,图片和内容滑块是一种极为常见和重要的元素.你可以从头开始编写自己的滑动效果,但是这将浪费很多时间,因为网络上已经有众多的优秀的 jQuery 滑块插件.当然,如果要从大量的 jQu ...
- centos 配置subversion svn
Subversion是一个自由,开源的版本控制系统. 1.安装: yum install subversion 2.配置 mkdir -p /var/svn/svnrepos #新建文件夹 svnad ...
- hive INSERT OVERWRITE table could not be cleaned up.
create table maats.account_channel ROW FORMAT DELIMITED FIELDS TERMINATED BY '^' STORED AS TEXTFILE ...
- gulp监听文件变化,并拷贝到指定目录(转)---参考记录
###暂时不支持目录修改.创建.删除.var gulp = require('gulp'); var fs = require('fs'); var path = require('path'); v ...
- C#使用System.IO.Path获取文件路径、文件名
class Program { static void Main(string[] args) { //获取当前运行程序的目录 string fileDir = Environment.Current ...
- <悟道一位IT高管20年的职场心经>笔记
1. 你一定会在某个时候惊讶地发现,原来当初你曾经硬着头皮挨过来的日子对你是那么的珍贵.2. "'老板就是老板'.这一点,你可能会忘,他一定不会忘.'老板不会总是老板'.这一点,他可能会忘, ...
- 修复Windows10系统的注册表?
在打开的管理员命令提示符窗口,输入如下命令: ———————————————————————————————— reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Mi ...