Reputation: 976
Forgive me if this question is a duplicate, I just have no idea how to phrase a Google search to come up with an answer.
First, I have an abstract class called AsyncRoutine<Msg>
, it's generic, and specifies some sort of Msg
type.
Next, I have an abstract AsyncMessageProvider<T extends AsyncRoutine>
, designed to deliver a Msg
to an AsyncRoutine
.
Let's say I create a subclass MyAsyncRoutine<Integer>
that extends AsyncRoutine
. I'd like to make a AsyncMessageProvider
that supports this class, so I'll subclass it, MyAsyncMessageProvider<MyAsyncRoutine>
making MyAsyncRoutine
its generic type.
Within MyAsyncMessageProvider
, I have a method, message(...)
that is called to pass a Msg
along, in this case an Integer
.
public class MyAsyncMessageProvider extends AsyncMessageProvider<MyAsyncRoutine> {
protected void message(Msg msg) { // compile error, doesn't know what 'Msg' is
}
}
How can I access the generic type of MyAsyncRoutine
(Integer
) within AsyncMessageProvider
? I basically want to make the message(...)
function lock to whatever I specify in <> as I'm subclassing AsyncMessageProvider
Is it possible to do this without reflection? Or is there a better way to do this in general? I'd like to avoid using reflection if possible.
Minimum Viable Example
Abstract class definitions:
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
in AsyncMessageProvider
so that it matches the generic Msg
from "AsyncRoutine<Msg>
" that I subclass AsyncMessageProvider
with?Upvotes: 1
Views: 79
Reputation: 424983
Add a type for it to your subclass:
public abstract class AsyncMessageProvider<Msg, Routine extends AsyncRoutine<Msg>> {
abstract void messageRoutine(Msg m);
}
——
Although this will compile, it’s the convention to use single letters for type names, ie:
public abstract class AsyncMessageProvider<T, Routine extends AsyncRoutine<T>> {
abstract void messageRoutine(T t);
}
Doing this makes it clear to readers what the type is, because they’re used to seeing single letter names. Someone reading this:
abstract void messageRoutine(Msg m);
would be excused if they thought the method was expecting an instance of a class named Msg
.
The problem become worse when you actually have a class named Msg
because the type of the same name shadows the corresponding class, which will make your coworkers sad.
Upvotes: 1