views:

41

answers:

2

I admit that I don't have a lot of experience with using Java Generics.

Right now, I'm retrofitting some old code with Generics to reduce/simplify existing code written by a colleague who has since left the company.

Basically, the system I'm working on has 6 request types: 1 General, and 5 specific that inherit from General. Each request type has associated Task types.

Here's the code where I'm having the trouble:

public class GeneralRequest implements Serializable {
    protected List<? extends GeneralTask> taskList;

    public <E extends GeneralTask> boolean addTask(E newTask) {
        boolean returnvalue = false;

        if(!this.taskList.contains(newTask)){
            returnvalue = taskList.add(newTask);
        }
        return returnvalue;
    }
}

public class AnnexationRequest extends GeneralRequest implements Serializable {
    public AnnexationRequest(List<AnnexationTask> tal) {
        this.taskList = tal;
    }
}

The problem is in the add line in GeneralRequest. As currently written, the taskList.add line bombs with

The method add(capture#6-of ? extends GeneralTask) in the type List<capture#6-of ? extends GeneralTask> is not applicable for the arguments (E)

Now, if I change the taskList declaration to

protected List<? super GeneralTask> taskList;

It fixes this problem, but then the child classes give me a different error, such as in AnnexationRequest:

Type mismatch: cannot convert from List<AnnexationTask> to List<? super GeneralTask>

How do I fix it so that addTask works properly and I can still set the task list from the constructor?

+3  A: 
public class GeneralRequest<E extends GeneralTask> implements Serializable {

  private final List<E> taskList;

  protected GeneralRequest(List<E> taskList) {
    this.taskList = taskList;
  }

  public boolean addTask(E newTask) {
    if(this.taskList.contains(newTask)) 
      return false;
    taskList.add(newTask);
    return true;
  }

}

public class AnnexationRequest extends GeneralRequest<AnnexationTask> {
  public AnnexationRequest(List<AnnexationTask> tal) {
    super(tal);
  }
}
erickson
Ah, I didn't think of putting the task type as a class generic. Whoops.
R. Bemrose
+1  A: 

You can’t put any element (other than null) into a Collection<?>.

However, you may use

protected List<GeneralTask> taskList;
DerMike
Yes, but I'm using `protected List<? extends GeneralTask>` which allows `GeneralTask`, and defining which subclass in the various Request class constructors.
R. Bemrose