public class TestA
{
TestA()
{
System.out.println("P ");
this.init(); } void init()
{
System.out.println("Q ");
} public static void main(String[] args)
{
TestB testb = new TestB();
}
}class TestB extends TestA
{
int i = 1; TestB()
{
super(); System.out.println(i + " ");
} void init()
{
System.out.println("C "); this.i = 2; System.out.println(i + " ");
}
}
你认为会输出什么结果?
{
TestA()
{
System.out.println("P ");
this.init(); } void init()
{
System.out.println("Q ");
} public static void main(String[] args)
{
TestB testb = new TestB();
}
}class TestB extends TestA
{
int i = 1; TestB()
{
super(); System.out.println(i + " ");
} void init()
{
System.out.println("C "); this.i = 2; System.out.println(i + " ");
}
}
你认为会输出什么结果?
如果改成了private,TestB中的init()方法就不构造覆盖了.在TestA中的this.init()调用的就不是TestB中的init()方法了.
问题主要了解类的初始化过程,想了解这方面的知识可以去看<<JVM规范>>.里边有详细的介绍.
public class TestA
{
TestA()
{
System.out.println("P ");
this.init(); } void init()
{
System.out.println("Q ");
} public static void main(String[] args)
{
TestB testb = new TestB();
}
} class TestB extends TestA
{
{
System.out.println("开始执行初始化!");
}
int i = 1;
TestB()
{
super();
int ii=i;
System.out.println(ii);
System.out.println(i + " ");
} void init()
{
System.out.println("C "); this.i = 2; System.out.println(i + " ");
}
} 可以看到初始块在init()方面执行之后进行.
public class TestA
{
TestA()
{
System.out.println("P ");
this.init(); } void init()
{
System.out.println("Q ");
} public static void main(String[] args)
{
TestB testb = new TestB();
}
} class TestB extends TestA
{
int i ;
{
System.out.println("开始执行初始化!");
i=1;
}
TestB()
{
super();
int ii=i;
System.out.println(ii);
System.out.println(i + " ");
} void init()
{
System.out.println("C "); this.i = 2; System.out.println(i + " ");
}
}
P
C
2
1
当将TastA中的init编程私有的时候输出结果是
P
Q
1
第一次是通过main函数调用TextB,而TextB继承于TextA
super();引用了超类对象
所以输出P
而TextB中修覆盖了超类中的构造函数,所以执行System.out.println("C"); this.i = 2; System.out.println(i);
输出C
2
最后因为TextB调用了超类,所以将i初始化为1
所以在执行System.out.println(i);时输出 1而改为私有后,子类不能覆盖超类的构造函数所以输出...
P
C
2
1
当将TastA中的init编程私有的时候输出结果是
P
Q
1
第一次是通过main函数调用TextB,而TextB继承于TextA
super();引用了超类对象
所以输出P
而TextB中修覆盖了超类中的构造函数,所以执行System.out.println("C"); this.i = 2; System.out.println(i);
输出C
2
最后因为TextB调用了超类,所以将i初始化为1
所以在执行System.out.println(i);时输出 1而改为私有后,子类不能覆盖超类的构造函数所以输出...
我标题上说过,有兴趣的朋友可以看看,题目来自SCJP考试相关书籍,只是想和大家分享一下,我没说是什么新题目,你“牛”,请绕道!谢谢!
结果:
P
Q
1
注意:输出的每行后面都有一个空格.
public class TestA
{
TestA() //4.调用到这里
{
System.out.println("P "); //5.打印P ;
this.init(); } //6.接着调用TestA的init()方法.void init() //7.运行到这里
{
System.out.println("Q "); //8.打印Q ;由于TestA的构造方法执行结束,返回到调用TestA构造方法的语句的下一句
} public static void main(String[] args)
{
TestB testb = new TestB(); //1.程序入口.栈区创建testb,指向堆区创建的TestB实例.调用了TestB的无参数构造方法.
}
} class TestB extends TestA
{
int i = 1; TestB() //2.程序调用的是这里
{
super(); //3.调用父类TestA的构造方法.System.out.println(i + " "); //9.输出1 ;
} void init()
{
System.out.println("C "); this.i = 2; System.out.println(i + " ");
}
}
结果:
P
C
2
1
注意:输出的每行后面都有一个空格. Java codepublic class TestA
{
TestA()
{
System.out.println("P ");
this.init(); } void init()
{
System.out.println("Q "); //8.打印Q ;由于TestA的构造方法执行结束,返回到调用TestA构造方法的语句的下一句
} public static void main(String[] args)
{
TestB testb = new TestB(); //1.程序入口.栈区创建testb,指向堆区创建的TestB实例.调用了TestB的无参数构造方法.
}
} class TestB extends TestA
{
int i = 1; TestB() //2.程序调用的是这里
{
super(); /*3.调用父类TestA的构造方法.创建testb的时候,由于TestB类是TestA的子类,而且由于子类TestB重写了TestA的init()方法,所以,创建testb时,testb中的init()方法是指向TestB重写后的init()方法,所以,这里调用的是TestB中的init()方法.*/System.out.println(i + " ");
} void init() //4.到这里
{
System.out.println("C "); //打印C
this.i = 2;
System.out.println(i + " "); //这里打印结果是2 下一个打印1 这里就不会分析了.
}
}
================
见7楼!自己可以在关节点打断点看一下实际运行情况!
TextB调用超类不是调用TextA的构造方法吗?
那为什么不是先
System.out.println("P ");
然后
this.init();
呢?
那不是
P
C
2
P
C
2
1了吗? 请赐教!