gdufo

           

          final 于 abstract 的問題

          第一題:
             class Something{
                  final int f;
                public void doSomething(){
                      System.out.println("f="+f)
                  }
              }
          第二題:
              abstract class Something{
                  private abstract void doSomething();
              }

          出錯在哪里?

          1)Something類在實(shí)例化的時候,會對成員變量進(jìn)行初始化,f會被賦值于0,按照語法結(jié)果就是f=0,可是實(shí)際上不是。Java編譯器為了減少人犯低級錯誤,對final修飾的變量不會再進(jìn)行默認(rèn)初始化,而是強(qiáng)制要求你顯示的賦一個值。Java編譯器考慮的可真周到啊,把它自己的語法都給推翻了。這么低級的程序我是寫不出來,所以我答錯了。
          2)這一題按照語法也沒錯了,可是為什么會被編譯不過去呢,說白了原因也就是Java編譯器為我們考慮太周到了,我們?yōu)槭裁匆诔橄箢愔卸x一個抽象方法,我們大家都知道抽象類是不能實(shí)例化,定義抽象方法就是為了定義一個子類來繼承該抽象類并實(shí)現(xiàn)它的抽象方法,但是題目中給定的抽象方法是private修飾的,也就是說它是不能被繼承的,也就是說我們根本不肯能寫出來一個能實(shí)現(xiàn)該抽象方法的類,說的更具體一點(diǎn)也就是這個抽象類被定義的毫無意義。Java編譯器真是太強(qiáng)了,連這個也被考慮到了,反正我是從來沒寫過這么低級的程序,更不會去寫出來一個毫無意義的抽象類。
          一句話,這兩道題考得不是final和abstract的語法,因?yàn)橥耆戏ǎ钦Z義,也就是Java編程規(guī)范。
           PS:關(guān)于為什么final修飾的成員變量不能被默認(rèn)初始化的問題,我想了很久,終于想明白了。我們大家都知道對象初始化分為三步:
          1)默認(rèn)初始化
          2)賦值初始化
          3)構(gòu)造方法初始化
          如果你在類中定義的是一個普通的成員變量非final成員變量,對該類的對象初始化時,該成員變量會嚴(yán)格按照以上三步進(jìn)行初始化。如果是該類的成員變量是用final修飾的,該類對象初始化時,對該成員變量的初始化按照常規(guī)也應(yīng)該由這三步組成,但是由于final修飾的變量是常量,不能進(jìn)行二次賦值,所以對該類型的變量初始化只能由其中一步來完成,不能出現(xiàn)交叉,否則會有編譯錯誤。下面是兩個可以正常編譯、運(yùn)行的寫法:
          /**
           * 
           * 
          @author <a href="mailto:flustar2008@163.com">flustar</a>
           * 
          @version 1.0 Creation date: Mar 22, 2008 7:18:18 PM
           
          */

          public class TestFinal {
              
          final int f=1;
              
          public void doSomething() {
                  System.out.println(
          "f=" + f);
              }

              
          public static void main(String args[]) {
                  TestFinal test 
          = new TestFinal();
                  test.doSomething();
              }

          }

          /**
           * 
           * 
          @author <a href="mailto:flustar2008@163.com">flustar</a>
           * 
          @version 1.0 Creation date: Mar 22, 2008 7:18:18 PM
           
          */

          public class TestFinal {
              
          final int f;
              
          public TestFinal(){
                  f
          =1;
              }

              
          public void doSomething() {
                  System.out.println(
          "f=" + f);
              }

              
          public static void main(String args[]) {
                  TestFinal test 
          = new TestFinal();
                  test.doSomething();
              }

          }
          下面再讓我們回過頭來看看下面這個程序它完全符合Java的語法:
          class Something{
                  
          final int f;
                
          public void doSomething(){
                      System.out.println(
          "f="+f)
                  }

              }

          為什么說它完全符合語法:
          1)按照常理會對f默認(rèn)初始化為0;
          2)程序中并沒有出現(xiàn)交叉,也就是說并沒有進(jìn)行二次賦值的可能。
          但是編譯器為什么不放過它呢?
          現(xiàn)在讓我們來假設(shè)一下如果不給f變量不顯示的賦一個值,它一定會被初始化為0,按照final的定義一旦被初始化一個值后就不能修改了,也就是說f的值只能是0了。再想想當(dāng)初我們?yōu)槭裁匆x一個final修飾的常量,難道僅僅就是為了得到一個默認(rèn)的不能修改的初始值嗎,這恐怕有違我們當(dāng)初定義final變量的真正意愿,那么我定義這個final變量又有何意義呢。所以在對對象進(jìn)行初始化時,發(fā)現(xiàn)對象的成員是用final修飾的就會查看它是否被顯示的賦了值,如果沒有就會不能正常編譯。這也是Java編程規(guī)范中為什么要強(qiáng)制對final變量進(jìn)行顯示賦值的真正原因。同樣的道理在abstract類里面定義private abstract方法,這個又有何意義呢?Java中把那些符合語法但不符合常規(guī)的用法定義成了規(guī)范,我想這也是Java為什么會有編程規(guī)范的原因吧,呵呵,扯遠(yuǎn)了。。。

          posted on 2008-08-14 21:39 gdufo 閱讀(563) 評論(0)  編輯  收藏 所屬分類: JAVA 基礎(chǔ)

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(6)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          Hibernate

          友情鏈接

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 吉首市| 茂名市| 闻喜县| 黑山县| 绥阳县| 天长市| 茂名市| 沾益县| 岗巴县| 灵武市| 泾源县| 阿合奇县| 盱眙县| 余庆县| 连城县| 静海县| SHOW| 长兴县| 清苑县| 宜都市| 神农架林区| 夏邑县| 奇台县| 沂南县| 额尔古纳市| 滨海县| 沿河| 灵丘县| 常德市| 二手房| 拉萨市| 县级市| 上虞市| 郴州市| 红原县| 调兵山市| 华亭县| 隆尧县| 桐梓县| 民权县| 遂昌县|