1

I am trying to construct an instance of a generic class, with a type parameter. For example if have ArrayList.class and I want to initialize it with class String.class, how do I do that? I understand I can use ArrayList.class.newInstance() to create a new instance, but I can't pass in a type parameter. I want to do new ArrayList<String>, but instead of for that specific example, any class that has a type parameter.

Specifically, I am trying to implement testing of different implementations of an interface, through subclassing of a JUnit test.

Community
  • 1
  • 1
saul.shanabrook
  • 3,068
  • 3
  • 31
  • 49
  • possible duplicate of [Instantiating a generic class in Java](http://stackoverflow.com/questions/1090458/instantiating-a-generic-class-in-java) – Robby Cornelissen Oct 29 '14 at 03:21
  • Basically, you can't because of [type erasure](http://docs.oracle.com/javase/tutorial/java/generics/erasure.html). – Elliott Frisch Oct 29 '14 at 03:23
  • 1
    @RobbyCornelissen I don't think it is. That is asking how to initialize the type within a generic class. I am asking how to initialize a generic class with a type. – saul.shanabrook Oct 29 '14 at 03:23
  • Since type information is erased at runtime and only useful for the static typecheck during compilation, why do you want to do this? In particular, there is *no difference* at runtime between an instance of `ArrayList` and an instance of `ArrayList`. – Thilo Oct 29 '14 at 03:23
  • Because then I know when I get, say, an item from my newly created ArrayList then I can use all the String methods on it – saul.shanabrook Oct 29 '14 at 03:25
  • How would you know that? Can you give a code example? – Thilo Oct 29 '14 at 03:25
  • 1
    Basically doing this: http://stackoverflow.com/questions/6724401/how-to-write-junit-tests-for-interfaces#comment28660208_6724555 ill update to show my example – saul.shanabrook Oct 29 '14 at 03:27
  • @Thilo you are right, I really don't need to. – saul.shanabrook Oct 29 '14 at 03:35

1 Answers1

0

I realized that can just return an initialization of the generic class, without the type paremeter and just cast it to that paremeter.

For example:

private Class<? extends List> implementation = ArrayList.class;

private <E> List<E> newList(Class<E> itemClass) {
    try {
        return (List)implementation.newInstance();
    } catch (Throwable x) {
       return null;
    }
}

@Test
public void test1() {
    List<String> testInstance = newList(String.class);
    testInstance.add('hey');
    assertEquals(3, testInstance.get(0).lenght());
}
saul.shanabrook
  • 3,068
  • 3
  • 31
  • 49
  • You shouldn't catch Throwable. Otherwise, yes you can do this this way. I would personally cast to `(List)` and use a temp variable to annotate the assignment with `@SuppressWarnings("unchecked")`. – Radiodef Oct 29 '14 at 03:49
  • you'll get a warning for this, though, about unchecked conversion. – Thilo Oct 29 '14 at 03:49
  • @Thilo It's safe though as long as you don't put something in the List while it's raw. – Radiodef Oct 29 '14 at 03:52
  • 2
    that's right. But I am assuming that List is only an example. This may or may not be safe with the real interface (and implementations) that are being tested here. – Thilo Oct 29 '14 at 03:53
  • Of course, triggering run time errors (like ClassCastException) is exactly what JUnit is for. So that should not be a problem. – Thilo Oct 29 '14 at 03:55