在一塊我寫的代碼,我有這樣一行:無法從ArrayList中<Parcelable>轉換爲ArrayList的<ClSprite>
AllSprites = (ArrayList<ClSprite>) savedInstanceState.getParcelableArrayList("AllSprites");
我得到一個錯誤有關從ArrayList<Parcelable>
的無效轉換到ArrayList<ClSprite>
。爲什麼這不合法?
在一塊我寫的代碼,我有這樣一行:無法從ArrayList中<Parcelable>轉換爲ArrayList的<ClSprite>
AllSprites = (ArrayList<ClSprite>) savedInstanceState.getParcelableArrayList("AllSprites");
我得到一個錯誤有關從ArrayList<Parcelable>
的無效轉換到ArrayList<ClSprite>
。爲什麼這不合法?
將ArrayList<Derived>
投射到ArrayList<Base>
或反之亦然是基本不安全的。這樣做會在類型系統中出現漏洞,如果您嘗試這樣做,Java將在運行時拋出ClassCastException
。
的原因是,我可以做這樣的事情:
ArrayList<Derived> derived = new ArrayList<Derived>();
ArrayList<Base> base = (ArrayList<Derived>) derived; // Not legal!
base.add(new Base()); // Just put a Base into the list, but it only holds Derived!
derived.get(0).doSomethingOnlyInDerived(); // Error! It's not really a Derived!
這是什麼原因,順便說一下,那陣列之間Java的隱式轉換斷了,爲什麼有ArrayStoreException
。這種情況在所有情況下都不安全。
這種轉換在Java中是非法的;不能將父列表轉換爲子列表。此外,投到ArrayList<X>
是危險和過度限制。您可以通過使AllSprites
的類型爲List<Parcelable>
來解決這兩個問題。
我該如何做到這一點,因爲我需要我的自定義類ClSprites中的函數。 –
您可以在使用它時在'List'中投射每個對象,或者您可以創建一個新的'List
其他人已經解釋了這個問題,但在這種情況下,它有一個非常簡單的解決方案。 只需離開演員陣容,您的代碼即可編譯。 :):
ArrayList<ClSprite> AllSprites = savedInstanceState.getParcelableArrayList("AllSprites");
爲什麼?
看看在getParcelableArrayList
方法的簽名:
public <T extends Parcelable> ArrayList<T> getParcelableArrayList(String key)
這是一個通用的方法,它的類型參數必須是Parcelable
一個孩子。如果你直接給它這樣一個變量:
ArrayList<ClSprite> AllSprites; // declaration somewhere
// ClSprite implements Parcelable
...
AllSprites = savedInstanceState.getParcelableArrayList("AllSprites");
編譯器可以推斷類型參數,所以沒有必要投了!推導後,簽名是這樣的:
public ArrayList<ClSprite> getParcelableArrayList(String key)
很顯然,我們沒有投從ArrayList<ClSprite>
到ArrayList<ClSprite>
。 :)
但是,爲什麼你有這個錯誤?如果您執行強制轉換並且不將該變量直接分配給此方法的返回值,那麼編譯器無法推導出類型參數,它只知道返回的類型爲ArrayList<Parcelable>
。在這種情況下,錯誤發生在別人已經解釋的地方。
此外,如果該方法不會是通用的,但這樣的:
public ArrayList<Parcelable> getParcelableArrayList(String key)
你不能返回值分配給AllSprites
,因爲沒有類型推演可言,而且不能從ArrayList<Parcelable>
轉換爲ArrayList<ClSprite>
。 儘管這很有意義,但Java對泛型使用type erasure,並且在運行時使這些事情變得不安全。
感謝您的好解釋,我試圖使用三元運算符設置ArrayList
感謝這個bug我永遠,我愛你 –
一個簡單的辦法是設置像這樣
ArrayList<ClSprite> AllSprites = savedInstanceState.<ClSprite>getParcelableArrayList("AllSprites")
這是對這個問題最簡單明智的答案。這應該是我所接受的答案。 – tasomaniac
非常好的答案! – Pauland
它與javac編譯器兼容(由AndroidStudio使用)。我在eclipse中使用的泛型轉換工作,但不適用於Android Studio。應該接受答案。 – bajicdusko
ArrayList<NewPost> news = new ArrayList<>();
news.addAll(List);
請爲您的代碼添加說明,以便海報可以更好地瞭解您的解決方案。 –
可以通過一種簡單的方式來理解: 較大的那些不能包含在較小的內容中 列表較大 ArrayList較小 您只能列出list.add(ArrayList); 希望能幫助你! –
返回元素類型......好了,什麼是你的** **的問題? –
[Java中的泛型]的可能重複(http://stackoverflow.com/questions/1794842/generics-in-java) – Thilo
看看標題,無法從ArrayList投射到ArrayList –