关于继承问题初始化的问题


今天在逛论坛时 看到个帖子提出的问题 出代码如下

<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

下面是一道面试题

看看下面两段代码


  1. //code_1 
  2. public class SingleInstance {  
  3.     private static SingleInstance si = new SingleInstance();    //注意这里  
  4.     public static int num_1;  
  5.     public static int num_2 = 0;  
  6.       
  7.     public SingleInstance() {  
  8.         num_1 ++;  
  9.         num_2 ++;  
  10. System.out.println(num_1 + ":" + num_2);
  11.     }  
  12.       
  13.     public static SingleInstance getInstance() {  
  14.         return si;  
  15.     }     
  16.       
  17.     public void print() {  
  18.         System.out.println(num_1 + ":" + num_2);  
  19.     }  
  20.       
  21.     public static void main(String[] args) {  
  22.         SingleInstance.getInstance().print();  
  23.     }  
  24.       
  25. }  
  26.   结果: 1:1
    1:0
  27.   
  28. //code_2  
  29. public class SingleInstance {  
  30.     public static int num_1;  
  31.     public static int num_2 = 0;  
  32.     private static SingleInstance si = new SingleInstance();    //注意,跟上面不一样了  
  33.       
  34.     public SingleInstance() {  
  35.         num_1 ++;  
  36.         num_2 ++;  
  37. System.out.println(num_1 + ":" + num_2);
  38.     }  
  39.       
  40.     public static SingleInstance getInstance() {  
  41.         return si;  
  42.     }     
  43.       
  44.     public void print() {  
  45.         System.out.println(num_1 + ":" + num_2);  
  46.     }  
  47.       
  48.     public static void main(String[] args) {  
  49.         SingleInstance.getInstance().print();  
  50.     }  
  51.       
  52. }  
  53. 结果: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


以上只是猜测!!!


再看下面代码

  1. //code_3
  2. 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();  
        }  
          
    }
  3. 结果:1:1
  4.     1:1


总结:





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值