Cannot call a function using List <SuperType> with list <SubType>

I created the following function in the Utils class:

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();
        }
}

I can not call

via:

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

OR using:

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

The function compiles correctly.

+3
source share
2 answers

Expected: There is no covariance in Java for generic types based on classes from the same hierarchy.

If you think about it, that makes sense. Consider this:

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

Now it Utils.addUsercan add UserVO(or something else that Serializable) to the list of admins, in violation of the type of the initial list:

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

However, since the usersinside addUsermatches the adminVoListoutside of it, you get non-admins on the list, which supposedly consists of admins.

, adminVoList

List<Serializable> adminVoList = new ArrayList<Serializable>();
+2

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!
+1

All Articles