今天在逛论坛时 看到个帖子提出的问题 出代码如下
<span style="font-size:14px;">class Fu{
int num = 5;
Fu(){
System.out.println(num);
show(); //55
System.out.println(num); //5
}
void show(){
System.out.println("55");
}
}
class Zi extends Fu{
int num = 3;
Zi(){
}
void show() {
System.out.println(num);
}
}
public class Demo {
public static void main(String[] args) {
Zi z = new Zi();
}
}</span>
这段程序的运行结果:
5
0
5
非常不可思议吧 为什么会有0这个值 貌似这段代码里没有0啊 再看
<span style="font-size:14px;">class Fu{
int num = 5;
Fu(){
System.out.println(num);
show(); //55
System.out.println(num); //5
}
void show(){
System.out.println("55");
}
}
class Zi extends Fu{
int num = 3;
Zi(){
}
void show() {
<span style="color:#ff0000;">System.out.println("子类show()方法") ; </span> </span>
<span style="font-size:14px;"><span style="white-space:pre"> </span>System.out.println(num);
}
}
public class Demo {
public static void main(String[] args) {
Zi z = new Zi();
}
}</span>
对上面代码做出修改
结果为:
5
子类show()方法
0
5
可以看到的确调用了子类的show方法 那么这个0应该是子类的num没错 可是为何是0呢? 再看
<span style="font-size:14px;">class Fu{
<span style="color:#ff0000;">String num = "5";</span>
Fu(){
System.out.println(num);
show(); //55
System.out.println(num); //5
}
void show(){
System.out.println("55");
}
}
class Zi extends Fu{
<span style="color:#ff0000;">String num = "3";</span>
Zi(){
}
void show() {
<span style="color:#ff0000;">System.out.println("子类show()方法") ; </span> </span>
<span style="font-size:14px;"><span> </span>System.out.println(num);
}
}
public class Demo {
public static void main(String[] args) {
Zi z = new Zi();
}
}</span>
结果:
5
子类show()方法
null
5
这下可以看出在父类构造器中调用了子类的show方法 这时子类只进行了jvm默认的初始化 并未进行赋值操作(即把3赋给num)
所以输出结果是0和null
本人没有深入了解过jvm 以上仅是个人推测而已!
结论:不要在父类构造器中调用任何需要用到子类成员变量的方法 因为子类还未完成初始化操作
--------------version1.0 2015.1.28
下面是一道面试题
看看下面两段代码
- //code_1
- public class SingleInstance {
- private static SingleInstance si = new SingleInstance(); //注意这里
- public static int num_1;
- public static int num_2 = 0;
- public SingleInstance() {
- num_1 ++;
- num_2 ++;
- System.out.println(num_1 + ":" + num_2);
- }
- public static SingleInstance getInstance() {
- return si;
- }
- public void print() {
- System.out.println(num_1 + ":" + num_2);
- }
- public static void main(String[] args) {
- SingleInstance.getInstance().print();
- }
- }
- 结果: 1:1
1:0 - //code_2
- public class SingleInstance {
- public static int num_1;
- public static int num_2 = 0;
- private static SingleInstance si = new SingleInstance(); //注意,跟上面不一样了
- public SingleInstance() {
- num_1 ++;
- num_2 ++;
- System.out.println(num_1 + ":" + num_2);
- }
- public static SingleInstance getInstance() {
- return si;
- }
- public void print() {
- System.out.println(num_1 + ":" + num_2);
- }
- public static void main(String[] args) {
- SingleInstance.getInstance().print();
- }
- }
- 结果:1:1
1:1
很奇怪吧 为什么两个的结果不一样
可以分析
在code_1中
编译期间对num_1 num_2 SingleInstance 进行了默认初始化
然后开始运行
因为java按自上而下的顺序运行
所以先执行了构造方法 num1++,num2++ 并输出了1:1
然后执行了num2=0; 再调用print()方法 输出了1:0
而在code_2中
先执行了num2=0 再调用构造方法输出1:1
再调用构造方法输出了1:1
以上只是猜测!!!
再看下面代码
- //code_3
- public class SingleInstance {
private static SingleInstance si = new SingleInstance(); //注意这里
public int num_1; //注意这里
public int num_2 = 0; //注意这里
public SingleInstance() {
num_1 ++;
num_2 ++;
System.out.println(num_1 + ":" + num_2);
}
public static SingleInstance getInstance() {
return si;
}
public void print() {
System.out.println(num_1 + ":" + num_2);
}
public static void main(String[] args) {
SingleInstance.getInstance().print();
}
}
- 结果:1:1
- 1:1
总结: