0

I have a ModelDecorator helper. I want it to have the following public API

class ModelDecorator<T>{
    public static <T> ModelDecorator<T> create(Class<T> clazz);
    public <SUPER> T from(SUPER fromInstance);
}

So, given classes A, B extends A, it can be used like this:

A a = new A();
B b = ModelDecorator.create(B.class).from(a);

But I want to have bounds on T and SUPER, so I make sure that only subclases can be instantiated using the API. At this moment, I can do:

C c = new C();
B b = ModelDecorator.create(B.class).from(c);

Where B DOES not inherit from C.

Any ideas? Thanks

Jason Oviedo
  • 459
  • 1
  • 5
  • 16
  • 1
    Possible duplicate of [Why can't a Java type parameter have a lower bound?](http://stackoverflow.com/questions/4902723/why-cant-a-java-type-parameter-have-a-lower-bound) – shmosel Feb 07 '17 at 07:29

1 Answers1

3

The only way I see for constraining your type parameter T to extend the type parameter S is to put those definitions into the class definition:

public class ModelDecorator<S, T extends S> {
    public static <S, T extends S> ModelDecorator<S, T> create(Class<T> clazz) { ... }
    public T from(S instance) { ... }
}

With these classes

class A {}
class B extends A {}
class C {}

you now can write the following code:

A a = new A();
B b1 = ModelDecorator.<A, B> create(B.class).from(a); // compiles fine

C c = new C();
B b2 = ModelDecorator.<C, B> create(B.class).from(c); // bound mismatch here

The second B creation now has a compiler error.

Unfortunately you now must explicitely provide the type parameters because the compiler is not able to infer the type A or C from a simple method call create(B.class).

Seelenvirtuose
  • 20,273
  • 6
  • 37
  • 66
  • This is in fact the way it is right now. I just don't like my API this way :( Am I too picky? – Jason Oviedo Feb 07 '17 at 07:52
  • I did not say a word about readability or usefulness. Maybe you are trying to solve a problem with a not appropriate technique ([XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem))? – Seelenvirtuose Feb 07 '17 at 08:02
  • @Seelenvirtuose I could be wrong but `create` is a `static` method. Would `S` and `T` in `public static ModelDecorator create` be the same type as that in `public class ModelDecorator`? If not, would using different type parameter for the `static` method and the `class` be a better option? – Chetan Kinger Feb 22 '17 at 12:01
  • @CKing No, the type parameters of a static method have nothing to do with the type parameters of the class. But ... I explicitely chose to give them the same name because the `create` method is a factory method that returns a `ModelDecorator`. Here the method's type parameters match exactly the _role_ of the class' type parameters. I don't fear any confusion at this point. – Seelenvirtuose Feb 22 '17 at 12:14