[英]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.