Re: [問題] 關於泛型 資料型態的疑問

看板java作者 (良葛格)時間10年前發表 (2015/05/28 10:07), 10年前編輯推噓0(000)
留言0則, 0人參與, 最新討論串5/6 (看更多)
※ 引述《LaPass (LaPass)》之銘言: : //下面這段OK : List<A> lista; : List<C> listc=new ArrayList<>(); : listc.add(new C()); : //lista = listc; // X : lista=(List)listc; //OK : A a=lista.get(0); //OK : System.out.print(a.getStr()); //印出 C 你可以瞭解一下「共變性」… Java的泛型並不具有共變性,不過可以使用型態通配字元?與extends來宣告變數,使其達 到類似共變性。 http://openhome.cc/Gossip/Java/Generics-extends.html 如果需要達到類似共變性的功能,可以用 ? extends,這樣就不用 CAST 來關掉編譯器 型態檢查功能 … List<? extends A> lista; List<C> listc = new ArrayList<>(); listc.add(new C()); lista = listc; // OK,類似共變性 A a=lista.get(0); //OK System.out.print(a.getStr()); //印出 C : //讓我們反過來試試看,這樣也是ok的 : List<A> lista=new ArrayList<>(); : List<C> listc; : lista.add(new C()); //OK 自動轉型 : //listc = lista; // X : listc=(List)lista; //OK : A a=listc.get(0); //OK : System.out.print(a.getStr()); //印出C 可以研究一下「逆變性」,如果Node<A>視為一種Node<B>,則稱Node具有 逆變性(Contravariance)。Java泛型並不支援逆變性,可以使用型態通配字元? 與super來宣告,以達到類似逆變性的效果 http://openhome.cc/Gossip/Java/Generics-super.html 如果需要達到類似逆變性的功能,可以用 ? super,這樣就不用 CAST 來關掉編譯器 型態檢查功能 … List<A> lista=new ArrayList<>(); List<? super C> listc; Lista.add(new C()); //OK 這不是自動轉型,這是符合 is-a 關係 listc = lista; // OK,類似逆變性 A a= (A) listc.get(0); // 確定沒問題,關掉編譯器型態檢查 System.out.print(a.getStr()); //印出C : //編譯OK但是執行不OK : List<A> lista=new ArrayList<>(); : List<C> listc; : lista.add(new A()); //OK 自動轉型 : //listc = lista; // X : listc=(List)lista; //OK : C c=listc.get(0); //編譯OK,執行錯誤 : ClassCastException: A cannot be cast to C 因為 CAST 實際上是關掉編譯器型態檢查的功能,實際上 listc 參考的實例, 當中是維護了一串 A 實例,你又編譯時期叫編譯器住嘴,當然執行時期出錯就得 自行收拾了 … XD : //再來看一個更驚悚的 : List<A> lista=new ArrayList<>(); : List<B> listb; : listb=(List)lista; //OK : listb.add(new B()); //OK.... 慢著,這很明顯有問題啊! : B b=listb.get(0); //可是還是被我拿出來了 : A a=lista.get(0); //編譯ok,執行時才出錯 : ClassCastException: B cannot be cast to A 這不是驚不驚悚的問題,CAST 是關掉編譯器型態檢查功能,在不確定內容物究竟為何 ,就進行 cast(或者是故意 cast),想不出錯很難吧! … XD 簡單來說,只有在確實清楚實例的型態為何下,再進行 CAST(也就是要編譯器別囉嗦) …XD : 因為java在運行時根本不會記住那個物件的泛型型別 是的,泛型提供的資訊只是給編譯器看的 ... -- 良葛格學習筆記 http://openhome.cc -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 49.215.51.149 ※ 文章網址: https://www.ptt.cc/bbs/java/M.1432807635.A.264.html ※ 編輯: JustinHere (49.215.51.149), 05/28/2015 18:10:27
文章代碼(AID): #1LPkZJ9a (java)
討論串 (同標題文章)
文章代碼(AID): #1LPkZJ9a (java)