0

Suppose I have the following:

interface I {
    // some getters and setters
}

class A implements I {
    // some methods
}

class B implements I {
    // some methods
}

interface J {
    // some getters and setters
}

class C implements J {
    // some methods
}

class D implements J {
    // some methods
}

I would like to be able to define a generic function along these lines:

static <S, T super S> List<T> f(String data, Class<S> sClass, Class<T> tClass) {
    List<T> lst = new ArrayList<>();
    S item = sClass.getInstance();  // try/catch omitted for brevity
    // set some fields of item based on data
    lst.add(item);  // this is allowed, since T super S
    return lst;
}

so that I can use it in

String s = "some data";
List<I> iLst = f(s, A.class, I.class);
iLst = f(s, B.class, I.class);
List<A> aLst = f(s, A.class, A.class);
List<B> bLst = f(s, B.class, B.class);

List<J> jLst = f(s, C.class, J.class);
jLst = f(s, D.class, J.class);
List<C> cLst = f(s, C.class, C.class);
List<D> dLst = f(s, D.class, D.class);

In other words, I would like to parameterize the element type in the returned list without explicitly making it I or J or any of the classes. Unfortunately, Java does not allow the T super S construct above. Any workaround?

user1408140
  • 639
  • 3
  • 9
  • 20
  • Could you use the instanceOf operator to check if the subclass is an instance of the superclass? – David Choweller Dec 03 '16 at 01:34
  • 1
    `instanceof` does not work on generic types because of erasure. In `f()`, you could use a check for `tClass.isAssignableFrom(sClass)` and an assignment with a cast `lst.add((T)item)` coupled with `@SuppressWarnings("unchecked")` on the entire `f()`, but this delegates type checking from the compile time to run time. I am looking for a compile time solution. – user1408140 Dec 03 '16 at 23:00

0 Answers0