I created following function in 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
using:
List<AdminVO> adminVoList = new ArrayList<AdminVO>
Utils.getUserIdCSVs(adminVoList);
OR using:
List<UserVO> userVoList = new ArrayList<UserVO>
Utils.getUserIdCSVs(userVoList);
The function compiles correctly.
This is expected: in Java, there is no covariance for generic types based on classes from the same hierarchy.
If you think about it, this makes sense. Consider this:
List<AdminVO> adminVoList = new ArrayList<AdminVO>();
Utils.addUser(adminVoList); // assume it expects ArrayList<Serializable>
Now Utils.addUser is free to add a UserVO (or anything else that's Serializable) to the list of admins, in violation of the type of the original list:
static addUser(List<Serializable> users) {
users.add(new UserV0("I am not an admin!"));
}
However, since users inside addUser is the same as adminVoList outside it, you end up with non-admins in the list that is supposedly composed of admins.
To work with this limitation, simply declare your adminVoList as
List<Serializable> adminVoList = new ArrayList<Serializable>();
List<AdminVO> is not a subclass of List<Serializable>.
Imagine it was:
List<AdminVO> list = new LinkedList<>();
List<Serializable> myList = list;
myList.add(new SomeConcreteSerializable());
//list contains an element which is not of type AdminVO!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With