`
jokermanager
  • 浏览: 140421 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

正确理解java构造函数内非final函数

阅读更多

大家都知道java构造 的使用方法吧,

可能大家都用它来进行对象的初始化。

就像下面这样一个例子。

 

public   class  Test
... {
    
public   static   void  main(String [] args)
    
... {
        Entry e 
=   new  Entry();
        System.out.println(
" the val value return ----> " + e.value());
    }

}

class  Entry
... {
    
public   int  val;
    
public  Entry()
    
... {
        val
= getVal();            // Entry构造函数
    }

    
    
public   int  getVal()
    
... {
        
return   6 ;
    }

    
    
public   int  value()
    
... {
        
return  val;                    // 返回val值
    }

}

 

运行Test,得到的值应该是什么?  对,就是6.

我们可以稍微加点东西,看看下面这个。

 

public   class  Test
...
... {
    
public   static   void  main(String [] args)
    ...
... {
        Entry1 e1 
=   new  Entry1();     // Entry改为 Entry1
        System.out.println( " the val value return ----> " + e1.value());
    }

}

class  Entry
...
... {
    
public   int  val;
    
public  Entry()
    ...
... {
        val
= getVal();            // Entry构造函数
    }

    
    
public   int  getVal()
    ...
... {
        
return   6 ;
    }

    
    
public   int  value()
    ...
... {
        
return  val;                    // 返回val值
    }

}




// 以下是新添加的代码


class  Entry1  extends  Entry                     
// 继承自Entry        
// 没有覆盖父类的构造函数 和 value函数

... {
    
public   int  val = 16 ;

    
public   int  getVal()
    
... {
        
return  val;
    }



}

 

结果是多少?

应该是16吧?

错了,结果是0.

-------------------------------------------------

怪了,怎么会这样呢?

明明这个函数已经有了实现的代码了呀?

事实是,当Entry1的getVal()函数开始被调用时,他的实例变量val初始化工作还未来得及进行!

这个getVal()函数是在父类Entry的构造函数中被调用的。

而父类的构造函数是被Entry1的构造函数自动调用的。

当运行权进入子类Entry1的getVal()时,它的val变量还来不及初始化,在这样的情况下,

所有的这些实例变量都仅仅只会被设置为缺省的处置。

所以此时val的值为0,被传到了调用的函数中。

于是输出结果为:0.

--------------------------

当我们的java程序构造函数调用非final的函数时,

就有可能发生上面的意外。

当然了,以上的错误不是很常见,不过,理解之后,

一旦遇上,就不会半天找不到解决方案了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics