Reputation: 773
I'm trying to refactor something. I have the following class hierarchy:
class BaseItem {..}
class ItemA extends BaseItem {..}
class ItemB extends BaseItem {..}
class BaseContext<T extends BaseItem> {..}
class ContextA extends BaseContext<ItemA> {..}
class ContextB extends BaseContext<ItemB> {..}
And 2 methods that a consumer needs to use:
public void methodA(ItemA) {..}
public void methodB(ItemB) {..}
Is it somehow possible to have a generic Consumer for these 2 methods ? Right now, I have 2 non-generic ones:
Consumer<ContextA> consumerA = ctx -> methodA(ctx.getItem());
Consumer<ContextB> consumerB = ctx -> methodB(ctx.getItem());
I would say this is not possible due to type erasure, I just want to make sure
Upvotes: 1
Views: 127
Reputation: 79808
It seems to me that you could use a generic method to convert your Item
consumers into Context
consumers. It might look something like this. It's not clear whether this would meet your requirement, as I'm not sure how you intend to use your context consumers.
public <T extends BaseItem, U extends BaseContext<T>> Consumer<U> wrap(Consumer<T> innerConsumer) {
return context->innerConsumer.accept(context.getItem());
}
You'd then have
Consumer<ContextA> consumerA = wrap(this::methodA);
Consumer<ContextB> consumerB = wrap(this::methodB);
Upvotes: 1
Reputation: 131324
The 2 methods expect specific subtypes of Item
not the common base type and you want to all the same declare as variable the base common class as generic.
That makes no sense.
The way you use actually :
Consumer<ContextA> consumerA = ctx -> methodA(ctx.getItem());
Consumer<ContextB> consumerB = ctx -> methodB(ctx.getItem());
is conform to your actual API :
public void methodA(ItemA) {..}
public void methodB(ItemB) {..}
If you want to declare :
Consumer<Context> consumerA = ctx -> methodA(ctx.getItem());
Consumer<Context> consumerB = ctx -> methodB(ctx.getItem());
You need an API such as :
public void methodA(Item) {..}
public void methodB(Item) {..}
Otherwise as alternative you can of course downcast. But that is really undesirable.
If you cannot refactor your API right now, you should stay to the actual design. And if you really need to make your code more "generic" and to program by interface you should start refactoring step by step.
Upvotes: 0