How would I express the following type relationship in Java generics:
class MyClass<T> { }
interface MyInterface<T extends MyClass> {
void m1(T<Integer> argument);
void m2(T<String> argument);
void m3(T<?> argument);
}
without a compiler complaint. Is that even possible? I want to make sure that all methods receive the same (sub)class of MyClass
while not breaking type-safety. In the domain, different subclasses og MyClass
would not make sence. Do I really have to list three generic type variables like this:
class MyClass<T> { }
interface MyInterface<T1 extends MyClass<Integer>,
T2 extends MyClass<String>, T3 extends MyClass<?>> {
void m1(T1 argument);
void m2(T2 argument);
void m3(T3 argument);
}
I feel like this is terrible to read and does neither express my intention as nicely as I wished. This question is related to my other question on generics Raw types inside of generic definition which still confuses me. Maybe someone can help! Thank you.
Well, I realized that I get because I cannot express this in Java:
class MyClass<T> { }
interface MyInterface<T extends MyClass> {
T<S> m1(S argument);
}
However, I found a rather fancy solution to this. Instead of manually upgrading my return type in every subinterface, I use Spoon to read and write the corresponding source code before compilation. The compiler sees my code as if I overrode the return types in every interface manually. This keeps my code in sync with the super interface on every Maven build and I do not have to worry about it any more.
This solution might not be for everybody, but it is the cleanest solution I could think of in the spirit of DNRY.