在我写的一段代码中,我有这一行:
AllSprites = (ArrayList<ClSprite>) savedInstanceState.getParcelableArrayList("AllSprites");
Run Code Online (Sandbox Code Playgroud)
我收到一个关于来自ArrayList<Parcelable>to 的无效演员的错误ArrayList<ClSprite>.为什么这不合法?
小智 25
一个简单的解决方案是设置返回元素类型
ArrayList<ClSprite> AllSprites = savedInstanceState.<ClSprite>getParcelableArrayList("AllSprites")
Won*_*abo 17
其他人已经解释了这个问题,但在这种情况下,有一个非常简单的解决方案.只需离开演员表,您的代码就会编译完毕.:):
ArrayList<ClSprite> AllSprites = savedInstanceState.getParcelableArrayList("AllSprites");
Run Code Online (Sandbox Code Playgroud)
为什么?
看一下getParcelableArrayList方法的签名:
public <T extends Parcelable> ArrayList<T> getParcelableArrayList(String key)
Run Code Online (Sandbox Code Playgroud)
这是一个通用方法,其类型参数必须是子类Parcelable.如果将它直接分配给这样的变量:
ArrayList<ClSprite> AllSprites; // declaration somewhere
// ClSprite implements Parcelable
...
AllSprites = savedInstanceState.getParcelableArrayList("AllSprites");
Run Code Online (Sandbox Code Playgroud)
编译器可以推断出类型参数,所以根本不需要演员!在推导之后,签名看起来像这样:
public ArrayList<ClSprite> getParcelableArrayList(String key)
Run Code Online (Sandbox Code Playgroud)
很明显,我们没有必须投入ArrayList<ClSprite>到ArrayList<ClSprite>.:)
但是你为什么会遇到这个错误?如果执行强制转换而不直接将变量赋值给此方法的返回值,则编译器无法推断出类型参数,它只知道返回的类型是ArrayList<Parcelable>.在这种情况下,错误发生在其他人已经解释过的地方.
此外,如果该方法不是通用的,但是像这样:
public ArrayList<Parcelable> getParcelableArrayList(String key)
Run Code Online (Sandbox Code Playgroud)
您无法将返回值分配给AllSprites,因为根本没有类型扣除,并且您无法转换ArrayList<Parcelable>为ArrayList<ClSprite>.即使它有意义,Java也会使用类型擦除进行泛型,并使这些内容在运行时不安全.
这是从根本上不安全投的ArrayList<Derived>一个ArrayList<Base>或反之亦然.这样做会在类型系统中打开一个漏洞,ClassCastException如果您尝试这样做,Java将在运行时抛出一个漏洞.
原因是我可以这样做:
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!
Run Code Online (Sandbox Code Playgroud)
顺便说一下,这就是Java在数组之间隐式转换被破坏的原因以及为什么会这样ArrayStoreException.在所有情况下,此演员阵容都不安全.
这种演员在Java中是非法的; 父母列表无法强制转换为子列表.此外,施法者ArrayList<X>是危险的并且过于严格.你可以通过制作AllSpritesbe 的类型来解决这两个问题List<Parcelable>.