2012-01-05 97 views
23
// Application ... 
Intent i = new Intent(); 
i.putExtra(EXTRA_FILE_UPLOAD_URIS, mGalleryAdapter.getItems()); 

Uri[] getItems() { return mItems; } 

// Service ... 
intent.getParcelableArrayExtra(EXTRA_FILE_UPLOAD_URIS); //works, returns Parcelable[] 
Uri[] uris = (Uri[])intent.getParcelableArrayExtra(EXTRA_FILE_UPLOAD_URIS); 
// ... Breaks with ClassCastException 

爲什麼投給Uri[]休息,當UriParcelable我不明白爲什麼這會發生ClassCastException異常

+0

發佈stacktrace。 – 2012-01-05 16:25:24

+0

Uri從Parcelable繼承嗎? – fge 2012-01-05 16:25:25

+0

Uri實現Parcelable – 2012-01-05 16:59:55

回答

19

不幸的是,沒有辦法像Java中那樣爲陣列進行類似的操作。你將不得不遍歷你的數組並單獨投射每個對象。

這樣做的原因是類型安全的JVM根本無法保證您的陣列中的內容可以被強制轉換爲開放的,而不必重複通他們,這就是爲什麼你必須重複他們並分別扮演他們。

基本上,因爲Parcelable可以被其他對象繼承,所以不能保證該數組僅包含Uri對象。然而,鑄造到超類型將起作用,從那時起,類型安全就沒問題。

+0

我認爲是相同的(因爲它在C#中是這樣的),所以我查了一下java數組協變,它似乎被支持(並且是類型安全的一個漏洞)。我的引用是否僅僅是當前的JVM過時了? :http://www.angelikalanger.com/Articles/Papers/JavaGenerics/ArraysInJavaGenerics.htm,http://c2.com/cgi/wiki?JavaArraysBreakTypeSafety – 2012-01-05 16:38:01

+1

我認爲類型安全性與泛型有關,它只限於編譯時。數組不被聚合。他們是參考,你可以做鑄造。 – 2012-01-05 16:41:40

+0

是正確的,但是Parcelable []是第一個新的Uri [...],所以即使Uri是Parcelable但Uri []不是Parcelable [] ...] – 2012-01-05 16:48:25

0

我覺得發生了什麼東西如下:

class Parent { } 

class MaleParent extends Parent { } 

class FemaleParent extends Parent { } 

如果方案是如上面的東西那麼下面會在運行時失敗:

Parent[] parents = new FemaleParent[]{}; 
MaleParent[] maleParents = (MaleParent[]) parents; 

東西如下不會引發異常:

Parent[] parents = new MaleParent[]{}; 
MaleParent[] maleParents = (MaleParent[]) parents; 
+0

爲什麼這麼多的父母? – Sayka 2015-10-31 08:20:53

26

使用此方法,它適用於我。

Parcelable[] ps = getIntent().getParcelableArrayExtra(); 
Uri[] uri = new Uri[ps.length]; 
System.arraycopy(ps, 0, uri, 0, ps.length); 
9

數組具有多態行爲 - 只有泛型類型沒有。

也就是說,如果Uri實現Parcelable然後

你可以說:

Parcelable[] pa = new Uri[size]; 
Uri[] ua = (Uri[]) pa; 

你不能說:

List<Parcelable> pl = new ArrayList<Uri>(); 

正如你看到的,我們可以投paUri[]。那麼問題是什麼?此ClassCastException發生在您的應用程序被終止並且稍後重新創建保存的數組時。當它被重新創建時,運行時不知道它是什麼類型的數組(Uri[]),它只是創建了Parcelable[]並將元素放入其中。因此ClassCastException當您嘗試將其投射到Uri[]

注意異常情況不會發生(理論上)當進程沒有中止與最初創建陣列(Uri[])被保存/恢復幾輪狀態之間重複使用。就像當你改變方向一樣。

我只是想澄清它爲什麼發生。如果你想要一個解決方案@solo提供一個體面的。

乾杯

+1

這是正確的答案。當我的服務試圖將Parcelable []從AccountManager的Bundle轉換到Account []時,我無意中重新出現了ClassCastException。發生這種情況後很少發生電話,最後 - 這是罪魁禍首! – user1643723 2014-08-15 11:08:50

相關問題