如果这个问题重复出现,请原谅我,我只是不知道如何用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
中访问Integer
(AsyncMessageProvider
)的通用类型?我基本上想使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
匹配?答案 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
的类时,问题会变得更加严重,因为同名的类型会遮盖相应的类,这会使您的同事感到难过。