0

In Java, how do we make a type parameter of a generic to take a type parameter itself? What I would really like to do is the following:

public class TransformerBase<T, TRANSFORMER<U> extends TransformerBase<U, TRANSFORMER>>
{

  public <O> TRANSFORMER<O> transform1(TransformFunction<T, O> f)
  {
    ...
  }
}

And one would extend the TransformerBase class and add their own transform methods, while retaining the original transform methods in the base class, like this:

public class MyTransformer<T> extends TransformerBase<T, MyTransformer>>
{

  public <O> MyTransformer<O> transform2(TransformFunction<T, O> f)
  {
    ...
  }
}

Then the user of the class can chain the method calls like this:

MyTransformer<String> input = new MyTransformer<>();
MyTransformer<String> result = input
  .transform1(new TransformFunction<String, Integer>() {...})
  .transform2(new TransformFunction<Integer, String>() {...});

This is similar to the problem outlined here but with the addition that the "Builder" itself takes a type parameter.

But the thing is, it does not look like Java supports this kind of construct. Is there another way to solve this problem?

I tried declaring the base class like this:

public class TransformerBase<T, TRANSFORMER extends TransformerBase<T, TRANSFORMER>>
{

  public <O, TFM_OUT extends TransformerBase<O, TFM_OUT>> TFM_OUT transform1(TransformFunction<T, O> f)
  {
    ...
  }
}

And the extended class:

public class MyTransformer<T> extends TransformerBase<T, MyTransformer<T>>
{
  public <O, TFM_OUT extends MyTransformer<O>> TFM_OUT transform2(TransformFunction<T, O> f)
  {
    ...
  }
}

The user can do this:

MyTransformer<Integer> input = new MyTransformer<>();

MyTransformer<String> t = input.transform1(new TransformFunction<Integer, String>(){...});

MyTransformer<Integer> result = t.transform2(new TransformFunction<String, Integer>(){...});

But in order for method chaining to work, the caller has to declare the type parameters explicitly, which kind of defeats the purpose of chaining:

MyTransformer<String> result = input
  .<String, MyTransformer<String>>transform1(new TransformFunction<Integer, String>(){ ... })
  .transform2(new TransformFunction<String, Integer>(){...});
Community
  • 1
  • 1
David Yan
  • 13
  • 2
  • http://stackoverflow.com/questions/24436871/very-confused-by-java-8-comparator-type-inference – shmosel May 17 '16 at 01:32
  • Yes @shmosel. Thanks for the link. That explains why we need to explicitly specify the types. But if Java can support specifying a type parameter taking another type parameter, this would not be needed... – David Yan May 18 '16 at 00:35

0 Answers0