Java Generics:为什么显式转换会导致编译器错误,但变量赋值不会

时间:2011-03-24 01:07:40

标签: java android

此块正确编译:

ArrayList<Baz> list = savedInstanceState.getParcelableArrayList("foo");
bar(list);

但此阻止错误表明ArrayList<Parcelable>无法转换为ArrayList<Baz>

bar((ArrayList<Baz>)savedInstanceState.getParcelableArrayList("foo"))

栏的形式为:

private void bar(ArrayList<Baz> food) {
}

Baz是一个实现Parcelable接口

的类

有没有办法可以完成直接演员而不必执行隐式演员并创建一个不必要的变量?

4 个答案:

答案 0 :(得分:1)

这两个块都是一样的。以此为例编译:

import java.util.ArrayList;

public class Test<T> {

    public void test(){
        ArrayList<T> list = (ArrayList<T>)foo();
        bar(list);
        bar((ArrayList<T>)foo());
    }
    private ArrayList<Integer> foo(){ return null; }    
    private void bar(ArrayList<T> food) {}  
}

答案 1 :(得分:1)

为了使用引用方法bar(ArrayList<T> food),您必须执行泛型类型调用,它将T替换为具体值。 T必须与其他类型绑定,引入bar(ArrayList<?> food)等通配符。

答案 2 :(得分:1)

我遇到了同样的问题,我的解决方案是创建一个将Parcelable转换为Baz的方法。 例如..

private ArrayList<Baz> convertParcelableToBaz(ArrayList<Parcelable> parcelableList){
    ArrayList<Baz> bazList= new ArrayList<Baz>();
    for (int i = 0 ; i < parcelableList.size(); i++){
        bazList.add((Baz)parcelableList.get(i));
    }
    return bazList;
}

这样

ArrayList<Baz> list = convertParcelableToBaz(savedInstanceState.getParcelableArrayList("foo"));

并且没有未选中的投射警告。

答案 3 :(得分:0)

你得到的错误是什么;我认为你只会得到一个警告,声明它是一个未经检查的演员。如果是这种情况,则需要将@SuppressWarnings("unchecked")添加到您要发布的函数中。老实说;你最好创建一个单独的变量来捕获返回值,然后发送变量。

你会在这里看到的一个问题是Java的类型擦除会伤害你。如果在调用函数和接收函数之间声明T不同,则当删除T时,没有任何东西阻止某人实际发送期望ArrayList为ArrayList的函数。这就是为什么这是一个类型安全问题。