rvb
rvb

Reputation: 479

Avoiding Java generics warnings?

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

Answers (2)

Tom
Tom

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

Scary Wombat
Scary Wombat

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

Related Questions