简体   繁体   English

Java从泛型方法调用非泛型方法

[英]Java call non-generic method from generic method

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:以及消费者需要使用的 2 种方法:

public void methodA(ItemA) {..}
public void methodB(ItemB) {..}

Is it somehow possible to have a generic Consumer for these 2 methods ?是否有可能为这 2 种方法设置一个通用的 Consumer? Right now, I have 2 non-generic ones:现在,我有 2 个非通用的:

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我会说这是不可能的,因为类型擦除,我只是想确保

It seems to me that you could use a generic method to convert your Item consumers into Context consumers.在我看来,您可以使用通用方法将您的Item消费者转换为Context消费者。 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);

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.这两种方法期望Item特定子类型而不是公共基类型,并且您希望将所有相同的变量声明为通用基公共类。
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 :符合您的实际 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 :您需要一个 API,例如:

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.如果你现在不能重构你的 API,你应该坚持实际的设计。 And if you really need to make your code more "generic" and to program by interface you should start refactoring step by step.如果你真的需要让你的代码更“通用”并按接口编程,你应该开始一步一步地重构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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