Simple
          回歸自我,努力奮斗
          posts - 0,comments - 0,trackbacks - 0
              這一段時間在寫代碼的時候,使用instanceof 關鍵字比較A類對象是不是B類時,出現了Incompatible conditional operand types A and B錯誤。當我試圖將A類對象強制轉換成B類((B)a)時,出現了Cannot cast from A to B錯誤,讓我百般不得其解。進過一段時間的探討和研究,總算有些體會,下面將逐一道來。先來看看幾個關鍵類的定義:
          public class A {
          }

          public class B {
          }

          public interface C {
          }

          public class D implements C {
          }

          public class Bootstrap {
              
          public static void main(String[] args) {
                  A a = new A();
          //        B b = (B)a; //Error:Cannot cast from A to B
          //        if(a instanceof B){ //Error:Incompatible conditional operand types A and B
          //        }
                  D d = new D();
                  
          if(d instanceof C){
                  }

              }

          }
              此例中,我定義了三個類和一個接口,A類與B類互不相關,D類繼承了接口C.在測試類中,我首先定義了一個A類對象a。當我試圖將對象a強制轉換成B時,編譯器拋出了Cannot cast from A to B,導致編譯無法通過。為什么編譯無法通過呢?我考慮的原因是這樣的?由于A類與B類毫無繼承關系,因此他們沒有轉換的必要,而且也無法將A類對象轉換成B類,因此,java編譯器在編譯的時候,就進行了檢查,如果沒有必要轉換,就認為是書寫錯誤,不允許編譯。這個原理也可應用于instanceof上,本身兩個類就毫無繼承關系,那么就沒有必要判斷對象a是不是類B了。
              接著,我定義了D類對象d,使用instanceof關鍵字判斷d是不是C.顯然對象d是屬于C的,這就好像:造紙廠繼承了抽象接口工廠,那么造紙廠當然也是工廠啦。下面,我們來看一下另外一種情況:
          public class Bootstrap {
              
          public static void main(String[] args) {
                  A a = new A();
                  
          if(a instanceof C){  //編譯能通過
                  }

                  C c = (C)a;
              }

          }
              我修改了測試類代碼,使用instanceof判斷了對象a是不是接口C,編譯竟然能通過,為什么呢?明明A類并未繼承接口C啊!!我想原因是這樣的,對應對象A來說,他有可能是A類本身,也可能時A類的子類(java運行默認向上轉型),java編譯器并未進一步確定對象A類的具體類型,如果對象a是A類的子類實例的話,那么A類的子類完全有可能繼承接口C,因為java類級別是單繼承的,而接口級別是多繼承的,因此,這種判斷就有意義了。這兒也可說明使用instanceof判斷A類對象是不是B類時出錯,因為java類級別采用單繼承,因此A類的子類也不能繼承自B,因此他們始終都無法扯上繼承關系。同樣的原理也用于類型轉換上。
              那么instanceof或者轉型在哪些地方使用才有意義呢?
              1.A繼承B
                  當A繼承自B時,A類對象a顯然是B類,舉個簡單的例子,Manager類繼承Employee類,那么經理類的實例manager當然也是Employee啦,因為即使你是經理,你也是公司的員工.
              2.B繼承A
                  當B繼承自A事,A類對象a有可能是B類,也有可能不是B類。舉個例子,當我們這樣實例化時A a = new B();那么對象a就是B類型的啦,但當我使用A a = new A()時,a就不是B類型的了。這就好像經理是員工,而員工不一定都是經理一樣。
              3.A與接口C
                  A直接繼承自接口C就不說了,來說一下A不直接繼承自接口C。由于A的子類有可能繼承自接口C,因此這種判斷也就存在意義了。假設我們這樣實例化:A a = new E(),其中E是A的子類,而且也繼承接口C。那么我們使用 a instanceof C時,就會是true。因為對象a確實是接口C。

              其他情況:
                  在泛型中使用instanceof時,會拋出Cannot perform instanceof check against parameterized type List<String>. Use instead its raw form List since generic type information will be erased at runtime錯誤,字面意思是instanceof關鍵字不能用于參數化的類型判斷,建議使用原生類型。這個可能是java遺留的歷史原因,因為在jdk5之前,java中沒有泛型概念,而instanceof在以前的版本中已經實現,因此使用該功能對泛型進行判斷時,會出現錯誤.




          posted on 2011-08-07 11:30 Mr.simple 閱讀(1470) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 封开县| 年辖:市辖区| 宝兴县| 瑞金市| 茌平县| 荔波县| 库伦旗| 库尔勒市| 陇西县| 大城县| 雷波县| 呼伦贝尔市| 仙居县| 丹江口市| 香港| 邢台市| 龙泉市| 五常市| 金溪县| 万山特区| 万盛区| 永城市| 桂东县| 鹰潭市| 博客| 福贡县| 祁阳县| 克什克腾旗| 齐齐哈尔市| 阳泉市| 资源县| 漳州市| 镇赉县| 辽中县| 榆林市| 扶沟县| 清镇市| 买车| 尤溪县| 宁陵县| 张掖市|