由阿里巴巴一道笔试题看Java静态代码块、静态函数、动态代码块、构造函数等的执行顺序
一、阿里巴巴笔试题:
public class Test {
public static int k = 0;
public static Test t1 = new Test("t1");
public static Test t2 = new Test("t2");
public static int i = print("i");
public static int n = 99;
private int a = 0;
public int j = print("j"); {
print("构造块");
} static {
print("静态块");
} public Test(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
} public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
} public static void main(String args[]) {
Test t = new Test("init");
}
}
输出:
1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态块 i=7 n=99
9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102
二、我们暂且先不看这道题,先回忆一下代码块、构造函数执行顺序的基本知识:
总体规则:静态代码块 -> 动态代码块 ->构造函数
静态代码块只在第一次new的时候执行一次,之后不再执行;动态代码块在每次new的时候都执行一次。
在不涉及继承的情况下:
1.静态代码块和静态成员变量在加载代码时执行,只执行一次,按照它们出现的顺序先后执行;
2.动态代码块在每次实例化对象时执行,在构造函数之前执行,多个动态代码块按照它们出现的顺序先后执行;
在涉及继承的情况下:
1.执行父类的静态代码块和静态成员变量定义,执行子类的静态代码块和静态成员变量定义;
2.执行父类的动态代码块,执行父类的构造函数;
3.执行子类的动态代码块,执行子类的构造函数;
4.如果父类构造函数中用到的函数被子类重写,那么在构造子类对象时调用子类重写的方法;
代码:
public class staticTest {
public static void main(String[] args) {
A a1 = new B();
}
} class A{
public A(){
System.out.println("A constructor.");
func();
} static{
System.out.println("class A static block.");
} private int ai = getAi(); {
System.out.println("class A dynamic block.");
} private static int asi = getAsi(); private int getAi(){
System.out.println("class A dynamic int.");
return 1;
} private static int getAsi(){
System.out.println("class A static int.");
return 0;
} public void func(){
System.out.println("A.func()");
}
} class B extends A{
public B(){
System.out.println("B constructor.");
func();
} static{
System.out.println("class B static block.");
} private int bi = getBi(); {
System.out.println("class B dynamic block.");
} private static int bsi = getBsi(); private int getBi(){
System.out.println("class B dynamic int.");
return 1;
} private static int getBsi(){
System.out.println("class B static int.");
return 0;
} public void func(){
System.out.println("B.func()");
}
}
输出:
class A static block.
class A static int.
class B static block.
class B static int.
class A dynamic int.
class A dynamic block.
A constructor.
B.func()
class B dynamic int.
class B dynamic block.
B constructor.
B.func()
三、对阿里巴巴笔试题的分析
public static int k = 0;
public static Test t1 = new Test("t1");
函数先执行到这里,在构造t1的过程中发生了什么呢,通过对程序打断点分析,我发现,程序并没有执行其中的静态代码块,而是执行非静态代码块,为什么呢?我的理解是,“静态代码块只在程序加载的时候运行,并且是按其出现顺序加载的”,而现在我们在构造一个新对象,属于程序加载的时候的一个分支,然后还会走回来继续加载剩下的未加载的静态代码块。所以在这次创建静态对象的过程中,之后执行其中的非静态代码块。
下面我们看到的两个*****中间的就是在执行该语句的过程中产生的分支:
**********
所以接下来执行的是:
private int a = 0;
public int j = print("j");
执行第二句的时候会调用
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}
然后执行动态代码块:
{
print("构造块");
}
然后调用构造函数:
public Test(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
}
这个顺序就是“动态代码块->构造函数"。
*************
然后跳出该分支,继续加载静态代码块:
public static Test t2 = new Test("t2");
执行此句会重复上面两个********之间的分支,这里不再赘述。
然后是:
public static int i = print("i");
public static int n = 99; static {
print("静态块");
}
最后执行main函数里面的部分,依次调用动态代码块和构造函数,不再赘述。
由阿里巴巴一道笔试题看Java静态代码块、静态函数、动态代码块、构造函数等的执行顺序的更多相关文章
- 从阿里巴巴笔试题看Java加载顺序
一.阿里巴巴笔试题: public class T implements Cloneable { public static int k = 0; public static T t1 = new T ...
- 由阿里巴巴笔试题看java加载顺序
一.阿里巴巴笔试题: public class T implements Cloneable { public static int k = 0; public static T t1 = new T ...
- 一道笔试题来理顺Java中的值传递和引用传递
题目如下: private static void change(StringBuffer str11, StringBuffer str12) { str12 = str11; str11 = ...
- Java中有关构造函数的一道笔试题解析
Java中有关构造函数的一道笔试题解析 1.详细题目例如以下 下列说法正确的有() A. class中的constructor不可省略 B. constructor必须与class同名,但方法不能与c ...
- 【笔试题】Java笔试题知识点
Java高概率笔试题知识点 Java语法基础部分 [解析]java命令程序执行字节码文件是,不能跟文件的后缀名! 1.包的名字都应该是由小写单词组成,它们全都是小写字母,即便中间的单词亦是如此 2.类 ...
- 一道笔试题和UML思想 ~
一句软件工程界的名言,让我想起了一个和一道笔试题有关的故事.希望更多的人了解 UML 背后的思想比他的语法更重要,是笔者写作本文的一点小愿望. 一.从一句软件工程名言说起 对很多事情的处理上,东西方都 ...
- Java静态变量的初始化(static块的本质)
Java静态变量的初始化(static块的本质) 标签: javaclassstring编译器jdk工作 2010-02-06 07:23 33336人阅读 评论(16) 收藏 举报 分类: Jav ...
- Java静态变量、静态块、构造块、构造函数、main函数、普通代码块的执行顺序
测试代码 public class SingleTest { public static String v = "StaticValue"; static { System.out ...
- 一道面试题与Java位操作 和 BitSet 库的使用
前一段时间在网上看到这样一道面试题: 有个老的手机短信程序,由于当时的手机CPU,内存都很烂.所以这个短信程序只能记住256条短信,多了就删了. 每个短信有个唯一的ID,在0到255之间.当然用户可能 ...
随机推荐
- PhotoSwipe.js 相册展示插件学习
PhotoSwipe.js官网:http://photoswipe.com/,在这个网站上可以下载到PhotoSwipe的文件以及相关的例子. 这个组件主要是用来展示图片.相册用的,还是很实用的. 一 ...
- angular post发送请求和GET发送请求,服务器端接收不到信息的问题
参数可能因为编码原因,服务器端无法接收到传递的值, 这时需要用到补丁来解决这个问题 1,下载一个http.patch.js文件,放入YII框架中的js/ng文件架内 2angularjs 创建模型部分 ...
- DEDECMS栏目自定义字段添加
用到的文件: catalog_add.htm 路径:\dede\templets\ catalog_edit.htm 路径:\dede\templets\ catalog_add.php 路径 ...
- 提高Order by语句查询效率的两个思路
提高Order by语句查询效率的两个思路 2011-03-01 13:07 水太深 ITPUB 字号:T | T 在MySQL数据库中,Order by语句的使用频率是比较高的.但是众所周知,在使用 ...
- 转:PHP的线程安全ZTS与非线程(NTS)安全版本的区别
原文来自于:http://blog.sina.com.cn/s/blog_94c21e8f0101s2ic.html Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和 ...
- 【译】UI设计基础(UI Design Basics)--为iOS设计(Design for iOS)(二)
2.1 为iOS设计(Design for iOS) iOS体现以下主题: 遵从:UI帮助用户理解界面内容并与内容交互,但绝不会与内容相互冲突. 清晰:文本在任何尺寸下都是清晰易读,图标精确易懂,装饰 ...
- BZOJ 1487 无归岛
Description Neverland是个神奇的地方,它由一些岛屿环形排列组成,每个岛上都生活着之中与众不同的物种.但是这些物种都有一个共同的生活习性:对于同一个岛上的任意两个生物,他们有且仅有一 ...
- 模态运行EXE程序
function ExecShowModal(APath: PChar; ACmdShow: Integer; ATimeout: Longword): Integer; var vStartupIn ...
- BAT 批处理实现循环备份N天文件夹
@echo off set today=%date:~0,4%%date:~5,2%%date:~8,2% xcopy /E /I E:\aaa e:\test\%today% for /f &qu ...
- 【HDOJ】3419 The Three Groups
记忆化搜索. /* 3419 */ #include <cstdio> #include <cstring> #include <cstdlib> #define ...