12

How To Instantiate a java.util.ArrayList with Generic Class Using Reflection? I am writing a method that sets java.util.List on target object. A target object and a generic type of list is knowing in runtime:

public static void initializeList(Object targetObject, PropertyDescriptor prop, String gtype) {
    try {
        Class clazz = Class.forName("java.util.ArrayList<"+gtype+">");
        Object newInstance = clazz.newInstance();
        prop.getWriteMethod().invoke(targetObject, newInstance);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
user592433
  • 121
  • 1
  • 1
  • 3

6 Answers6

15

An object doesn't know about its generic type at execution time. Just create a new instance of the raw type (java.util.ArrayList). The target object won't know the difference (because there isn't any difference).

Basically Java generics is a compile-time trick, with metadata in the compiled classes but just casting at execution time. See the Java generics FAQ for more information.

Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • just for not creating duplicate answers, using reflection is just like doing `new ArrayList()` because a "generic class" is interpreted as an `Object` at runtime – Yanick Rochon Jan 27 '11 at 15:27
7

There's no need to do any reflection for creating your List. Just pass in some additional type information (usually done by passing a class of the correct type).

public static <T> List<T> createListOfType(Class<T> type) {
    return new ArrayList<T>();
}

Now you have a list of the required type you can presumably/hopefully set it directly on your targetObject without any reflection.

alpian
  • 4,398
  • 16
  • 18
2

Generics are a compile-time only "trick".

Reflection is runtime-only.

Basically, you can't - you can only create a "raw" ArrayList. If you need to pass it into methods that take generic parameters, casting it directly after construction will be safe (regardless of the "unchecked" warning). In this example, there's no compile-time type safety anyway due to using general Objects, so no casting is needed.

Andrzej Doyle
  • 97,637
  • 30
  • 185
  • 225
  • 1
    Generics is not completely a compile-time only thing. Concrete type parameters in field, method and class definitions are actually present in the bytecode and can be acquired at runtime via reflection. – Michael Borgwardt Jan 27 '11 at 15:29
0

Generics only work at compile time, therefore if you're using reflection, they won't be available.

See more about this here.

biziclop
  • 46,403
  • 12
  • 73
  • 97
0

An object doesn't know about its generic type at execution time. Just create a new instance of the raw type (java.util.ArrayList). The target object won't know the difference (because there isn't any difference).

ram singh
  • 1
  • 4
0

Generics is largely a compile time feature. What you are trying to do is the same as

public static void initializeList(Object targetObject, PropertyDescriptor prop, String gtype) {
    prop.getWriteMethod().invoke(targetObject, new ArrayList());
}

Note: This could change with Types in Java 7.

Peter Lawrey
  • 498,481
  • 72
  • 700
  • 1,075