泛型传递泛型的泛型

时间:2019-07-18 00:00:15

标签: java

如果这个问题重复出现,请原谅我,我只是不知道如何用Google搜索来表达答案。

首先,我有一个名为AsyncRoutine<Msg>的抽象类,它是通用的,并指定了某种Msg类型。

接下来,我有一个抽象的AsyncMessageProvider<T extends AsyncRoutine>,旨在将Msg传递到AsyncRoutine

比方说,我创建了一个扩展MyAsyncRoutine<Integer>的子类AsyncRoutine。我想制作一个支持此类的AsyncMessageProvider,所以我将其子类化,MyAsyncMessageProvider<MyAsyncRoutine>将其MyAsyncRoutine设为其通用类型。

MyAsyncMessageProvider内,有一个方法message(...)被调用来传递Msg,在这种情况下为Integer

public class MyAsyncMessageProvider extends AsyncMessageProvider<MyAsyncRoutine> {

    protected void message(Msg msg) { // compile error, doesn't know what 'Msg' is
    }

}

如何在MyAsyncRoutine中访问IntegerAsyncMessageProvider)的通用类型?我基本上想使message(...)函数锁定为我在子类化AsyncMessageProvider

时在<>中指定的内容。

是否可以不进行反射?还是总体上有更好的方法?我希望尽可能避免使用反射。

最小可行示例

抽象类定义:

public abstract class AsyncRoutine<Msg> {
 // Implementation not important
}
public abstract class AsyncMessageProvider<Routine extends AsyncRoutine<Msg>> { // Compile error, cannot resolve Msg
    abstract void messageRoutine(Msg m); 
}
  • 如何在Msg中使用AsyncMessageProvider,以使其与我为Msg子类化的“ AsyncRoutine<Msg>”中的通用AsyncMessageProvider匹配?

1 个答案:

答案 0 :(得分:1)

为此类型添加一个子类型:

public abstract class AsyncMessageProvider<Msg, Routine extends AsyncRoutine<Msg>> {
    abstract void messageRoutine(Msg m); 
}

-

尽管可以编译,但习惯上使用单个字母作为类型名称,即:

public abstract class AsyncMessageProvider<T, Routine extends AsyncRoutine<T>> {
    abstract void messageRoutine(T t); 
}

这样做可以使读者清楚地知道类型是什么,因为他们习惯于看到单个字母的名称。有人在读这篇文章:

abstract void messageRoutine(Msg m);
如果

认为该方法需要一个名为Msg class 实例,则会被原谅。

当您实际上有一个名为Msg的类时,问题会变得更加严重,因为同名的类型会遮盖相应的类,这会使您的同事感到难过。