Search code examples
javagenericsraw-types

Generic types of type variables?


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.


Solution

  • 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.