无法使用List <子类型> </subtype> </supertype>使用List <supertype>参数调用函数

时间:2014-02-13 14:08:32

标签: java generics collections

我在Utils类中创建了以下函数:

public class Utils{
    public static String getUserIdCSVs(List<Serializable> voList) {
            StringBuilder csv = new StringBuilder();
            if(voList != null){ 
                for(Serializable serializable :voList){
                    UserVO userVO = null;
                    if(serializable != null && serializable instanceof AdminVO){
                        userVO = ((AdminVO)serializable).getUserVO(); 
                    }
                    if(serializable != null && serializable instanceof UserVO){
                        userVO = (UserVO)serializable;
                    }
                    csv.append(userVO.getUserId()+",");
                }
            }
            return csv.toString();
        }
}

我不能打电话

使用:

List<AdminVO> adminVoList = new ArrayList<AdminVO>
Utils.getUserIdCSVs(adminVoList);

或使用:

List<UserVO> userVoList = new ArrayList<UserVO>
Utils.getUserIdCSVs(userVoList);

该功能正确编译。

2 个答案:

答案 0 :(得分:2)

这是预期的:在Java中,基于同一层次结构的类的泛型类型没有协方差。

如果你考虑一下,这是有道理的。考虑一下:

List<AdminVO> adminVoList = new ArrayList<AdminVO>();
Utils.addUser(adminVoList); // assume it expects ArrayList<Serializable>

现在Utils.addUser可以免费将UserVO(或其他任何Serializable)添加到管理员列表中,这违反了原始列表的类型:

static addUser(List<Serializable> users) {
    users.add(new UserV0("I am not an admin!"));
}

但是,由于users内的addUser与其外的adminVoList相同,因此您最终会在列表中找到非管理员,而这些管理员应该由管理员组成。

要处理此限制,只需将adminVoList声明为

即可
List<Serializable> adminVoList = new ArrayList<Serializable>();

答案 1 :(得分:1)

List<AdminVO>不是List<Serializable>的子类。

想象一下:

List<AdminVO> list = new LinkedList<>();
List<Serializable> myList = list;
myList.add(new SomeConcreteSerializable()); 
//list contains an element which is not of type AdminVO!