简体   繁体   中英

How to add elements to this generic list?

I have a list declared as below into which I intend to add objects.

List<RecursableAction<Recursable, AbstractContext>> actions = new ArrayList<>();

I have an IdGeneratorItemAction that looks like the below:

public class IdGeneratorItemAction implements RecursableAction<Item, IdGeneratorContext> {
    private IdGeneratorContext context;

    @Override
    public void act(Item recursable) {
    }
}

The interface RecursableAction looks like this:

public interface RecursableAction<R extends Recursable, C extends AbstractContext> {
    void act(R recursable);
}

I try to create an instance of IdGeneratorItemAction and add it to the actions list as follows:

RecursableAction<Recursable, AbstractContext> action = new IdGeneratorItemAction();
actions.add(action);

When I attempt to do that, I get the below compilation error:

RecursableAction<Recursable, AbstractContext> action = new IdGeneratorItemAction();
                                                       ^
Type mismatch: cannot convert from IdGeneratorItemAction to RecursableAction<Recursable,AbstractContext>

I tried to change the delcaration of actions to

List<RecursableAction<? extends Recursable, ? extends AbstractContext>> actions = new ArrayList<>();

But when I do that, I am no longer able to iterate on the actions .

for (RecursableAction<? extends Recursable, ? extends AbstractContext> action : actions) {
    action.act(recursable);
    ^
    The method act(capture#1-of ? extends Recursable) in the type RecursableAction<capture#1-of ? extends Recursable,capture#2-of ? extends AbstractContext> is not applicable for the arguments (Recursable)
}

How to solve this problem?

Without knowing the context it's hard to advise. Clearly you can't add an IdGeneratorItemAction to a List<RecursableAction<Recursable, AbstractContext>> because IdGeneratorItemAction is a RecursableAction<Item, IdGeneratorContext> and these are not compatible (in the same way as you can't assign a List<String> to a variable that expects a List<Object> ). But likewise you can't call act(recursable) on a RecursableAction<? extends Recursable, ? extends AbstractContext> RecursableAction<? extends Recursable, ? extends AbstractContext> RecursableAction<? extends Recursable, ? extends AbstractContext> because you don't know what kind of Recursable it expects.

If you are in a context where you know all the actions are compatible then you're OK, for example

public static <R extends Recursable> void doStuff(
      List<? extends RecursableAction<R, ?>> actions, R recursable) {
  for(RecursableAction<R, ?> action : actions) {
    action.act(recursable);
  }
}

public static void main(String[] args) {
  List<RecursableAction<Item, IdGeneratorContext>> actions = new ArrayList<>();
  actions.add(new IdGeneratorItemAction());
  doStuff(actions, new Item());
}

but if not then I don't think you can achieve what you want without a cast somewhere or other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM