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

时间:2018-11-04 18:57:18

标签: java generics

我正在尝试重构某些东西。我具有以下类层次结构:

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> {..}

以及消费者需要使用的2种方法:

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

这两种方法是否有可能具有通用的Consumer?现在,我有2个非通用的:

Consumer<ContextA> consumerA = ctx -> methodA(ctx.getItem());
Consumer<ContextB> consumerB = ctx -> methodB(ctx.getItem());

我会说由于类型擦除而无法实现,我只想确保

2 个答案:

答案 0 :(得分:1)

在我看来,您可以使用通用方法将Item个使用者转换为Context个使用者。它可能看起来像这样。目前尚不清楚这是否满足您的要求,因为我不确定您打算如何使用上下文使用者。

public <T extends BaseItem, U extends BaseContext<T>> Consumer<U> wrap(Consumer<T> innerConsumer) {
    return context->innerConsumer.accept(context.getItem());
}

您将拥有

Consumer<ContextA> consumerA = wrap(this::methodA);
Consumer<ContextB> consumerB = wrap(this::methodB);

答案 1 :(得分:0)

这2种方法期望Item的特定子类型不是通用基类型,并且您希望所有相同的基类都声明为泛型。
没道理
实际使用方式:

Consumer<ContextA> consumerA = ctx -> methodA(ctx.getItem());
Consumer<ContextB> consumerB = ctx -> methodB(ctx.getItem());

符合您的实际API:

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

如果要声明:

Consumer<Context> consumerA = ctx -> methodA(ctx.getItem());
Consumer<Context> consumerB = ctx -> methodB(ctx.getItem());

您需要一个API,例如:

public void methodA(Item) {..}
public void methodB(Item) {..}

否则,您当然可以垂头丧气。但这确实是不可取的。

如果您现在无法重构API,则应遵循实际设计。而且,如果您确实需要使代码更“通用”并按界面编程,则应该逐步进行重构。