我不明白为什么发生这种ClassCastException

// 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 

为什么当UriParcelable时候,对Uri[]的演员呢?

Solutions Collecting From Web of "我不明白为什么发生这种ClassCastException"

不幸的是,没有办法像Java那样对数组进行转换。 你将不得不遍历你的数组,并单独投射每个对象。

这样做的原因是安全types, JVM不能确保你的数组的内容可以被转移到Uri,而不必迭代它们,这就是为什么你必须迭代它们并单独施放它们。

基本上,因为Parcelable可以被其他对象inheritance,所以不能保证Array只包含Uri对象。 然而,铸造到超types将工作,从那时起,types安全就可以了。

使用这种方法,它为我工作。

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

数组有多态行为 – 只有genericstypes没有。

也就是说,如果Uri实现了Parcelable

你可以说:

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

你不能说:

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

正如你所看到的,我们可以回到Uri[] 。 那么问题是什么? 这个ClassCastException发生在你的应用程序被终止并且以后保存的数组被重新创build时。 当它被重新创build时,运行时不知道它是什么types的数组( Uri[] ),所以它只是创build一个Parcelable[]并将元素放入其中。 因此,当您尝试将其转换为Uri[]时, ClassCastException

请注意,当进程未被终止并且原始创build的数组( Uri[] )在状态保存/恢复轮回之间重用时,exception不会发生(理论上)。 就像当你改变方向一样。

我只是想澄清为什么发生。 如果你想要一个解决scheme@solo提供了一个体面的。

干杯

我认为发生的事情如下:

 class Parent { } class MaleParent extends Parent { } class FemaleParent extends Parent { } 

如果情况如上所述,则在运行时以下将失败:

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

下面的东西不会引起exception:

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