Reputation: 479
I am new to Java's generics feature and I'm having some difficulty with it in one of my methods. Eclipse is giving me several warnings, which I would like to avoid. The method takes a boolean flag as its argument and returns either a List<Integer>
or a List<String>
depending on the boolean. I could split the method into two, one for each case, but I would rather not so as to keep the logic in one place.
Simplified method with the warnings as comments:
private <T> List<T> getList(boolean returnInt) {
// List is a raw type. References to generic type List<E> should be parameterized
List returnList;
if (returnInt) {
returnList = new ArrayList<Integer>();
} else {
returnList = new ArrayList<String>();
}
if (mShowNew) {
if (returnInt) {
// Type safety: The method add(Object) belongs to the raw type List.
// Refs to generic type List<E> should be parameterized.
returnList.add(ID_NEW);
} else {
// Type safety: The method add(Object) belongs to the raw type List.
// Refs to generic type List<E> should be parameterized.
returnList.add("New");
}
}
if (mResume) {
if (returnInt) {
returnList.add(ID_RESUME);
} else {
returnList.add("Resume");
}
}
// Pattern continues
// Type safety: The expression of type List needs unchecked conversion to
// conform to List<T>
return resultList;
}
What can I change to avoid these warnings? If there is a better way altogether, a push in the right direction would be greatly appreciated.
Upvotes: 0
Views: 90
Reputation: 17577
If the argument is just used to determine the nested type of the resturnd list, then you could except the type as the argument to specify the desired list type.
This could look like this:
private <T> List<T> getList(Class<T> listType) {
if (!(listType.getClass().equals(Integer.class)
|| listType.getClass().equals(String.class))) {
throw new IllegalArgumentException(
String.format("Type '%s' is currently not supported.", listType.getClass().getName()));
}
// v--- the missing type specification was causing the warnings you mentioned
List<T> returnList = new ArrayList<>();
if (mShowNew) {
if (listType.getClass().equals(Integer.class)) {
returnList.add(ID_NEW);
} else {
returnList.add("New");
}
}
if (mResume) {
if (listType.getClass().equals(Integer.class)) {
returnList.add(ID_RESUME);
} else {
returnList.add("Resume");
}
}
//...
return resultList;
}
Upvotes: 0
Reputation: 44834
create a new class that holds both an Integer
and a String
E.g.
public class Result {
private String stringResult = null;
private Integer intResult = null;
}
fill this in as required and use it as
List<Result> returnList;
also of course having your method return this
private List<Result> getList(boolean returnInt) {
Upvotes: 1