阿里笔试题 关于类的静态加载顺序 求高人解答

soarzx 2013-09-23 09:43:01
要求写出程序输出内容:


public class StaticTest {

public static int k = 0;
public static StaticTest t1 = new StaticTest("t1");
public static StaticTest t2 = new StaticTest("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");

{
print("构造快");
}

{
print("静态块");
}

public StaticTest(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
++i;
}

public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
return ++n;
}
public static void main(String[] args) {
StaticTest t = new StaticTest("init");
}

}

jdk1.6下测试输出的内容如下:
1:j i=0 n=0
2:构造快 i=1 n=1
3:静态块 i=2 n=2
4:t1 i=3 n=3
5:j i=4 n=4
6:构造快 i=5 n=5
7:静态块 i=6 n=6
8:t2 i=7 n=7
9:i i=8 n=8
10:j i=9 n=99
11:构造快 i=10 n=100
12:静态块 i=11 n=101
13:init i=12 n=102

我一开始还没觉得复杂,后来越想月复杂,越想月糊涂,求指点
...全文
1733 38 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
平菇虾饺 2014-02-22
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390705686?page=1#post-396796266 23楼。有注释你去看看去
wokaonagekao 2013-09-27
  • 打赏
  • 举报
回复
这里面有一个递归初始化的过程,可以参考JLS初始化那块的内容 大概意思是说,可能会有多个进程执行初始化,因此初始化过程是同步的。 这个题目里面可以看到有一个递归初始化过程。 JLS上面说,当一个进程企图初始化时,首先需要acquire一把锁,这道题实行static对象的初始化时,是获得了这把锁的,但是当前进程会发现这个类正在初始化,而且是当前进程发起的,所以只要release LOCK and complete,效果就是,当前进程以为静态块都加载完了,接下来该轮到instance variable initializer,然后是instance initialization block,然后是construct部分,OK,第一个静态对象加载完成。记得CSDN上某位大神说把static去掉就会StackOverflowError,因为如果不是静态的话会一直递归的初始化下去。 第二个静态对象执行过程和第一个类似。 这时候还是执行到static int i = print("i");了,这时会答应i的语句 i已经搞定,现在可以到static block了,剩下的过程都好理解了。。。。。
阿飞的蝶 2013-09-25
  • 打赏
  • 举报
回复
引用 29 楼 weidu23 的回复:
[quote=引用 20 楼 soarzx 的回复:] [quote=引用 19 楼 u011269546 的回复:] 我第一次也没弄出来 关键是这个题 太混乱了 !!!
这个题确实不好搞,很繁琐,考的也很全面,笔试只能当个炮灰去了。[/quote] 楼主,我直接做了个总结,里面就是你这个问题,我自己的总结,你看看:http://user.qzone.qq.com/1078577864/blog/1380008857#!app=2&via=QZ.HashRefresh&pos=1380008857 看完记得评价哦 ... [/quote]大哥,日至在哪呢?进不去呢
艳沐石 2013-09-25
  • 打赏
  • 举报
回复
引用 33 楼 weidu23 的回复:
[quote=引用 31 楼 yanmushi 的回复:] [quote=引用 30 楼 weidu23 的回复:] [quote=引用 28 楼 soarzx 的回复:] [quote=引用 27 楼 shachundaiben 的回复:] 请看http://blog.csdn.net/hyl713/article/details/11925071
很不错,转换后的class更容易理解[/quote] 另外还想说一句,静态块先执行 ? 未必 。 你看完我写的,就明白了 ... [/quote] 从第一个static开始执行的,对吧~[/quote] 呵呵,如果说第一个,那就 ... 哈哈 ![/quote] 其实,这道题目,主要是因为第二个static语句,再次调用了该类的构造函数,使得给大家一些误区了。
weidu23 2013-09-25
  • 打赏
  • 举报
回复
引用 35 楼 yjjy0921 的回复:
[quote=引用 29 楼 weidu23 的回复:] [quote=引用 20 楼 soarzx 的回复:] [quote=引用 19 楼 u011269546 的回复:] 我第一次也没弄出来 关键是这个题 太混乱了 !!!
这个题确实不好搞,很繁琐,考的也很全面,笔试只能当个炮灰去了。[/quote] 楼主,我直接做了个总结,里面就是你这个问题,我自己的总结,你看看:http://user.qzone.qq.com/1078577864/blog/1380008857#!app=2&via=QZ.HashRefresh&pos=1380008857 看完记得评价哦 ... [/quote]大哥,日至在哪呢?进不去呢[/quote] 由于楼主评分完毕,更悲剧的是,他根本没进我的帖子看,于是,我关掉了访问权限!sorry! 加个Q,我告诉你:1078577864
绝对在乎妮 2013-09-24
  • 打赏
  • 举报
回复
学习了
isoft__java 2013-09-24
  • 打赏
  • 举报
回复
静态块与静态成员是谁排在前面谁先加载,之前一直认为最先加载的是静态块里面的了
Mourinho 2013-09-24
  • 打赏
  • 举报
回复
估计LZ没仔细看过think in java,上面的例子比这个更复杂
soarzx 2013-09-24
  • 打赏
  • 举报
回复
引用 19 楼 u011269546 的回复:
我第一次也没弄出来 关键是这个题 太混乱了 !!!
这个题确实不好搞,很繁琐,考的也很全面,笔试只能当个炮灰去了。
TableMiao 2013-09-24
  • 打赏
  • 举报
回复
我第一次也没弄出来 关键是这个题 太混乱了 !!!
soarzx 2013-09-24
  • 打赏
  • 举报
回复
引用 12 楼 u011269546 的回复:
类加载顺序: * 1.加载类的静态属性(非静态不管) * 这里加载的是:public static int k = 0; * 然后加载:public static StaticTest t1 = new StaticTest("t1"); * 因为此处进行了类的实例化所以 * 1.1加载类的非静态属性 * 这里是:public int j = print("j"); * 运行完这个方法接着 * 1.2顺序加载类中的非static代码块(static暂时不加载) * 这里是:print("构造快");和print("静态块"); * 运行完接着 * 1.3加载类的构造方法 * 这里是:public StaticTest(String str) * 运行完(一个静态属性的实例就完成了) * 2.继续加载类的静态属性 * 这里加载的是:public static StaticTest t2 = new StaticTest("t2"); * 2.1重复(1.1-1.3) * 3.继续加载类的静态属性 * 这里加载的是:public static int i = print("i"); * 运行完接着 * 4.继续加载类的静态属性 * 这里加载的是:public static int n = 99; * 不管你n原来是多少现在为99 * 接着 * 5.(如果有static代码块,在这里先加载,这个里面没有所以加载主函数)加载主函数 * 这里加载的是:StaticTest t = new StaticTest("init"); * 因为此处进行了类的实例化所以 * 5.1 * 重复1.1-1.3 * 5.2 * 因为public static int print(String str)这个方法返回++n * 所以n从99开始累加 * 运行完OK了
按照你的思路走了一遍,很顺畅,很清晰。基本功好扎实啊。
DACHAO613 2013-09-24
  • 打赏
  • 举报
回复
感谢楼主的问题,让自己又巩固了一下知识!

安顺序之行代码!当程序执行到创建静态对象t1的时候,创建一个t1对象!创建t1对象时之行public int j,不会之行public static int i,因为静态变量属于类,不属于对象!
soarzx 2013-09-24
  • 打赏
  • 举报
回复
引用 13 楼 DACHAO613 的回复:
那不是非静态代码块吗?
原题是有static关键字的,我粗心忘写了,谢谢指正。
soarzx 2013-09-24
  • 打赏
  • 举报
回复
引用 11 楼 yanmushi 的回复:
我觉得这道题目的静态块,是不是应该这样 static { print("静态块"); } 因为,这样考点就基本全了~~~
对的,粗心大意了,应该有static的,谢谢指正。
TableMiao 2013-09-24
  • 打赏
  • 举报
回复
楼主 一步一步来就能出来 这段代码就是乱的很 理清思路就行了
DACHAO613 2013-09-24
  • 打赏
  • 举报
回复
那不是非静态代码块吗?
TableMiao 2013-09-24
  • 打赏
  • 举报
回复
类加载顺序: * 1.加载类的静态属性(非静态不管) * 这里加载的是:public static int k = 0; * 然后加载:public static StaticTest t1 = new StaticTest("t1"); * 因为此处进行了类的实例化所以 * 1.1加载类的非静态属性 * 这里是:public int j = print("j"); * 运行完这个方法接着 * 1.2顺序加载类中的非static代码块(static暂时不加载) * 这里是:print("构造快");和print("静态块"); * 运行完接着 * 1.3加载类的构造方法 * 这里是:public StaticTest(String str) * 运行完(一个静态属性的实例就完成了) * 2.继续加载类的静态属性 * 这里加载的是:public static StaticTest t2 = new StaticTest("t2"); * 2.1重复(1.1-1.3) * 3.继续加载类的静态属性 * 这里加载的是:public static int i = print("i"); * 运行完接着 * 4.继续加载类的静态属性 * 这里加载的是:public static int n = 99; * 不管你n原来是多少现在为99 * 接着 * 5.(如果有static代码块,在这里先加载,这个里面没有所以加载主函数)加载主函数 * 这里加载的是:StaticTest t = new StaticTest("init"); * 因为此处进行了类的实例化所以 * 5.1 * 重复1.1-1.3 * 5.2 * 因为public static int print(String str)这个方法返回++n * 所以n从99开始累加 * 运行完OK了
艳沐石 2013-09-24
  • 打赏
  • 举报
回复
我觉得这道题目的静态块,是不是应该这样 static { print("静态块"); } 因为,这样考点就基本全了~~~
soarzx 2013-09-24
  • 打赏
  • 举报
回复
引用 1 楼 Cecil_911 的回复:
本来我是搞清楚的,又搞乱了,这贴顶上去
6楼的分析蛮不错的,可以看看,理一理,相信会明白许多。
soarzx 2013-09-24
  • 打赏
  • 举报
回复
引用 7 楼 u010111184 的回复:
果然我基础不行。我只能写出前两步。后面不知道怎么运行了。
这题能做出来,说明类的加载顺序,静态方面基础知识已经很扎实了。
加载更多回复(18)

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧