黑马程序员技术交流社区
标题:
出个题目大家来答
[打印本页]
作者:
朱东方
时间:
2012-7-12 23:40
标题:
出个题目大家来答
class Root
{
static
{
System.out.println("1:Root静态构造代码块") ;
}
{
System.out.println("2:Root普通构造代码块") ;
}
public Root() {
System.out.println("3:Root构造函数") ;
}
}
class Mid extends Root
{
static {
System.out.println("4:Mid静态构造代码块") ;
}
{
System.out.println("5:Mid普通构造代码块");
}
public Mid() {
System.out.println("6:Mid无参构造函数") ;
}
public Mid(String msg) {
this ();
System.out.println("7:Mid有参构造函数"+msg) ;
}
}
class Leaf extends Mid
{
static {
System.out.println("8eaf静态构造代码块") ;
}
{
System.out.println("9eaf普通构造代码块") ;
}
public Leaf() {
super("疯狂java讲义");
System.out.println("10eaf有参构造函数") ;
}
}
public class demo {
public static void main(String[] args) {
new Leaf() ;
}
}
大家看看这个是怎么执行的。做上注释。明天我发答案
作者:
林康春
时间:
2012-7-13 00:02
哥们,前几天我也遇到这个问题,刚好有前辈回答了
下面我来总结他们的解答吧.
要弄明白程序的执行顺序首先要明白 继承继承静态代码块构造代码块构造函数 的执行顺序,他们的顺序是:
父类静态代码块>>子类静态代码块>>父类构造代码块>>父类构造函数>> 子类构造代码块>>子类构造函数。
执行步骤(个人见解)
class Root //第5步:找到Root,开始执行
{
static { //第6步:由于有静态代码块,先执行静态代码块,进行初始化,打印1:Root静态构造代码块
System.out.println("1:Root静态构造代码块") ;
}
{ //第9步:执行父类的构造代码块,打印2:Root普通构造代码块
System.out.println("2:Root普通构造代码块") ;
}
public Root() { //第10步:执行父类构造函数,打印3:Root构造函数
System.out.println("3:Root构造函数") ;
}
}
class Mid extends Root //第4步:找到Mid类,他又继承了Root,再去找Root类
{
static { //第7步:Root初始化完成后寻找子类,也有静态代码块,先执行,并打印4:Mid静态构造代码块
System.out.println("4:Mid静态构造代码块") ;
}
{ //第11步:执行性次构造代码块 打印5:Mid普通构造代码块
System.out.println("5:Mid普通构造代码块");
}
public Mid() { //第12步:执行此构造函数,打印6:Mid无参构造函数
System.out.println("6:Mid无参构造函数") ;
}
public Mid(String msg) { //第13步:执行此构造函数打印7:Mid有参构造函数"+msg,msg由Leaf()调用super传入疯狂java讲义,所以打印Mid有参构造函数疯狂java讲义
this ();
System.out.println("7:Mid有参构造函数"+msg) ;
}
}
class Leaf extends Mid
{
static { //第8部:理由同第六步,打印8eaf静态构造代码块。静态代码块都完成了,再找父类的构造代码块
System.out.println("8eaf静态构造代码块") ;
}
{ //第14部最后执行子类的构造代码块,打印9eaf普通构造代码块
System.out.println("9eaf普通构造代码块") ;
}
public Leaf() { //第2步,要new对象,找到Leaf的构造函数
super("疯狂java讲义"); //第3步,调用父类,并且有参数 疯狂java讲义
System.out.println("10eaf有参构造函数") ; //第15步,打印10eaf有参构造函数
}
}
public class demo {
public static void main(String[] args) {
new Leaf() ; //第1步:找到main方法开始执行这一句,
}
}
再总结一下:
哥们你这代码太让人崩溃了……不过为了技术分,咱拼了!
关于对象初始化的问题,我也找了很多资料,写了很多测试代码,我就来说说吧
对象的初始化,有以下几项原则:
1.静态代码块,静态变量的显式初始化,会在类加载完成后进行
2.只是建立对象引用,类是不会加载的,只有要new 对象时,或者需要访问静态成员时,类才会加载
3.这条很重要,new出子类之前,会先去加载父类,也就是说先加载父类,再加载子类
4.构造代码块和成员变量的显式初始化会优先于构造函数执行,并且,构造代码块会在每一个构造函数之前执行
5.子类构造函数一定会调用父类的构造函数,如果程序员不调用,那么系统就默认调用父类的无参构造函数,当然程序员自己也可以手动调用
6.这条非常重要,构造函数并不是用来new对象的,而是对new出来的对象进行初始化的!!!
好,明确了这几点,我们再看代码,从main函数开始:
1.new Leaf(); 使用Leaf()来创建Leaf对象,在这之前先加载父类 Mid,并使用Mid的构造代码块和 Mid(String msg) 对自己进行初始化,,
2.而Mid(String msg)又调用了Mid(),同理,在这之前又去加载Mid 的父类 Root了,并使用Root的构造代码块和 Root() 对自己进行初始化
3.此时Root加载完毕,接着执行他的静态代码区(这里我们不考虑Object,要不就太麻烦了)
4.Root 搞完了就该 Mid了,同样的,先执行静态代码区
5.Mid 加载完了 就该 Leaf了,同样执行 静态代码块,
6.所有的类都类加载完毕,静态代码区也都执行完了,那接下来就该是对象的初始化了
7.初始化的顺序就是:先使用父类的构造代码块和父类的构造函数初始化,在调用自己的构造代码块和构造函数
8.接下来就不多说了,先执行构造代码块,再执行构造函数,按照父子类构造函数的调用顺序逆向进行
按照上面所说,打印顺序为:
1:Root静态构造代码块
4:Mid静态构造代码块
8Leaf静态构造代码块
2:Root普通构造代码块
3:Root构造函数
5:Mid普通构造代码块
6:Mid无参构造函数
7:Mid有参构造函数疯狂java讲义
9Leaf普通构造代码块
10Leaf有参构造函数
再次感谢前辈对我的指导!
作者:
朱东方
时间:
2012-7-13 00:04
好厉害,哥们一来抢楼来吧。优活动
作者:
王红霞
时间:
2012-7-13 02:52
本帖最后由 王红霞 于 2012-7-13 03:05 编辑
1-静态代码块优先于构造代码块执行
2-执行子类时要先加载父类的构造函数,即加载leaf的时候 先加载root 再加载Mid
class Root
{
static//
静态代码块 ;类一加载 static就加载了 所以这是第一步输出
1
{
System.out.println("1:Root静态构造代码块") ;
}
{ //构造代码块
System.out.println("2:Root普通构造代码块") ;//
然后即便是依次执行父类的构造函数和子类的构造函数
4
}
public Root()
{ //定义父类
System.out.println("3:Root构造函数") ;//
5
}
}
class Mid extends Root //子类
{
static
{
//静态代码块 类一加载 static也即加载 所以这是第二部输出
2
System.out.println("4:Mid静态构造代码块") ;
}
{
System.out.println("5:Mid普通构造代码块");//
6
}
public Mid()
{
System.out.println("6:Mid无参构造函数") ;//
7
}
public Mid(String msg)
{
this ();
System.out.println("7:Mid有参构造函数"+msg) ;//
8
}
}
class Leaf extends Mid
{
static
{
System.out.println("8eaf静态构造代码块")
;//类一加载 static就加载了 这是第三步输出
3
}
{
System.out.println("9eaf普通构造代码块") ;//
9
}
public Leaf()
{
super("疯狂java讲义");
System.out.println("10eaf有参构造函数") ; //
10
}
}
public class Demo
{
public static void main(String[] args)
{
new Leaf() ;
}
}
打印结果如下图:
12.jpg
(22.93 KB, 下载次数: 19)
下载附件
2012-7-13 03:03 上传
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2