Search code examples
javagenericstype-systemsnested-generics

Java generics, how can I define a type that needs to be a generics with one param?


Let me give you a concrete example.

I have an interface that is called FutureConverter. The idea is to be able to convert CompletableFuture to another type. It is useful if you want to use my library in another JVM language.

I have a method that returns CompletableFuture<MyClass> and I want to convert the return type to MyGenericFutureType<MyClass>. However, I don't know how to give MyGenericFutureType a parameter.

I want to be able to do something like that:

MyMainClass<FUTURE> {
    private final FutureConverter<FUTURE> converter;
    FUTURE<MyClass> myFunction() {
        //let's imagine soSomething is a method defined somewhere that returns CompletableFuture<MyClass>
        CompletableFuture<MyClass> myFuture = doSomething();
        return converter.convert(myFuture);
    }
}

Now the type param FUTURE doesn't know he needs a param itself so it doesn't compile obviously.

  1. Is this even possible?
  2. If yes, how do I do it?

I know that Java Type System can be limited, but I hope that this is possible somehow.

Thank you very much in advance!


Solution

  • Define your FutureConverter interface as follows:

    public interface FutureConverter<S, T> {
        MyGenericFutureType<T> convert(CompletableFuture<S> source);
    }
    

    In your concrete converter (from CompletableFuture<Foo> to MyGenericFutureType<Foo> you just implement FutureConverter<Foo>.

    You might also want to have a look at Spring's converters: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html#core-convert

    https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main/java/org/springframework/core/convert/converter/Converter.java