简体   繁体   English

无法从ArrayList强制转换 <Parcelable> 到ArrayList <ClSprite>

[英]Cannot cast from ArrayList<Parcelable> to ArrayList<ClSprite>

In a piece of code I've written, I have this line: 在我写的一段代码中,我有这一行:

         AllSprites = (ArrayList<ClSprite>) savedInstanceState.getParcelableArrayList("AllSprites");

I'm getting an error about an invalid cast from an ArrayList<Parcelable> to ArrayList<ClSprite> . 我收到有关从一个无效的转换错误ArrayList<Parcelable>ArrayList<ClSprite> Why isn't this legal? 为什么这不合法?

一个简单的解决方案是设置返回元素类型

ArrayList<ClSprite> AllSprites = savedInstanceState.<ClSprite>getParcelableArrayList("AllSprites")

Others already explained the problem, but in this case, there is a very simple solution for it. 其他已经说明了问题,但在这种情况下,对于这是一个非常简单的解决方案。 Simply leave the cast, and your code will compile. 只需离开演员表,您的代码就会编译完毕。 :) : :):

ArrayList<ClSprite> AllSprites = savedInstanceState.getParcelableArrayList("AllSprites");

Why? 为什么?

Take a look at the signature of the getParcelableArrayList method: 看看在签名getParcelableArrayList方法:

public <T extends Parcelable> ArrayList<T> getParcelableArrayList(String key)

It's a generic method whose type parameter must be a child of Parcelable . 这是一个通用的方法,它的类型参数必须是一个孩子Parcelable If you assign it directly to a variable like this: 如果将它直接分配给这样的变量:

ArrayList<ClSprite> AllSprites; // declaration somewhere
                                // ClSprite implements Parcelable
...

AllSprites = savedInstanceState.getParcelableArrayList("AllSprites");

the compiler can deduce the type parameter, so there is no need the cast at all! 编译器可以推断类型参数,所以没有必要投了! After deducing, the signature would look like this: 在推导之后,签名看起来像这样:

public ArrayList<ClSprite> getParcelableArrayList(String key)

It is clear the we do not have to cast from ArrayList<ClSprite> to ArrayList<ClSprite> . 很明显,我们不必从ArrayList<ClSprite>ArrayList<ClSprite> :) :)

But why did you got this error? 但是你为什么会遇到这个错误? If you perform a cast and not assign the variable directly to the return value of this method, the compiler cannot deduce the type parameter, it only knows that the returned type is ArrayList<Parcelable> . 如果执行强制转换而不直接将变量赋值给此方法的返回值,则编译器无法推导出类型参数,它只知道返回的类型是ArrayList<Parcelable> And in this case, the error takes places what the others already explained. 在这种情况下,错误发生在其他人已经解释过的地方。

Also if the method would not be generic, but like this: 此外,如果该方法不是通用的,但是像这样:

public ArrayList<Parcelable> getParcelableArrayList(String key)

you could not assign the return value to AllSprites , because there is no type deduction at all, and you cannot convert from ArrayList<Parcelable> to ArrayList<ClSprite> . 你不能指定返回值AllSprites ,因为没有类型推演可言,而且不能从转换ArrayList<Parcelable>ArrayList<ClSprite> Even though it would make sense, Java uses type erasure for generics, and makes these things unsafe at runtime. 即使它有意义,Java也会使用类型擦除进行泛型,并使这些内容在运行时不安全。

It is fundamentally unsafe to cast an ArrayList<Derived> to an ArrayList<Base> or vice-versa. ArrayList<Derived>转换为ArrayList<Base>或反之亦然是不安全的。 Doing so opens up a hole in the type system, and Java will throw a ClassCastException at runtime if you try this. 这样做会在类型系统中打开一个漏洞,如果您尝试这样做,Java将在运行时抛出ClassCastException

The reason is that I could do something like this: 原因是我可以这样做:

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!

This is the reason, by the way, that Java's implicit conversions between arrays are broken and why there's ArrayStoreException . 顺便说一下,这就是Java在数组之间的隐式转换被破坏以及为什么存在ArrayStoreException This cast isn't safe under all cases. 在所有情况下,此演员阵容都不安全。

That cast is simply illegal in Java; 这种演员在Java中是非法的; a list-of-parent can't be cast to a list-of-child. 父母列表无法强制转换为子列表。 Furthermore, the cast to ArrayList<X> is dangerous and overly restrictive. 此外,对ArrayList<X>是危险的并且过于严格。 You could fix both problems by making the type of AllSprites be List<Parcelable> . 您可以通过使AllSprites的类型为List<Parcelable> AllSprites List<Parcelable>来解决这两个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM