I have defined the class:

public abstract class AbstractFruitHandler<T extends Fruit> {
   public abstract void handle(T fruit);
   ...
}

Where Fruit is an interface.

Example of a class that extends this abstract class:

public class AppleHandler extends AbstractFruitHandler<Apple> {
    @Override
    public void handle(Apple a) {
             ...
         }
    }
}

Where Apple is a class that implements Fruit.

I have defined a map of these fruit handlers as such:

Map<FruitType, AbtractFruitHandler<? extends Fruit> handlers = Map.of(
     FruitType.APPLE, new AppleHandler(),
     FruitType.BANANA, new BananaHandler()
);

Now here is where I begin to see issues. Consider the code below:

for (Fruit f : fruits) {
    AbstractFruitHandler handler = handlers.get(f.getType());
    handler.handle(f);
}

This code works fine! The only issue is that the IDE warns about Raw use of parameterized class 'AbstractFruitHandler'.

To suppress this warning, I tried to update this code to:

for (Fruit f : fruits) {
    AbstractFruitHandler<? extends Fruit> handler = handlers.get(f.getType());
    handler.handle(f);
}

But then I get a compilation error saying that the required type of the handle method is capture of ? extends Fruit, and not the provided type Fruit.

I should also note that I get the same error when I try to explicitly pass in a concrete implementation of Fruit.

If possible, I'd like to know why I see this compilation error even though I am passing in objects that are a subtype of Fruit.

I'm also wondering what other possible solutions there are.

0

There are 0 best solutions below