1

Possible Duplicate:
Create instance of generic type in Java?

I only found out that Java doesn't let you construct new instances of generic type arguments after trying to write this:

public static <C extends JSONSerializable> List<C> JSONtoList(JSONArray data) {
    List<C> list = new ArrayList<C>();
    for (int i = 0; i < data.length(); i++){
        list.add(new C(data.get(i)));
    }
    return list;
}

This doesn't compile, but I think its obvious what I'm trying to do. How can I do it?

Community
  • 1
  • 1
Drew
  • 12,578
  • 11
  • 58
  • 98
  • can you include the error message? I don't think Java let's you do constructors on generic objects. – Brian Nickel Mar 29 '12 at 02:26
  • @BrianNickel you are correct. This is an example of how I would do it if Java supported this. – Drew Mar 29 '12 at 02:34
  • The generics implementation is actually bigger things I miss from working with .Net (http://msdn.microsoft.com/en-us/library/sd2w2ew5.aspx). You would think with beans being such a common component in Java, they would make it easy. – Brian Nickel Mar 29 '12 at 03:43

2 Answers2

1

If you are using GSON, this is actually quite easy:

public static <C extends JSONSerializable> List<C> jsonToList(JsonArray data, Class<C> type) {
    Gson gson = new Gson();
    List<C> list = new ArrayList<C>();
    for (JsonElement e : data)
        list.add(gson.fromJson(e, type));
    return list;
}

Otherwise, you will need to use reflection or the newInstance method of Class.

Tyler Treat
  • 14,640
  • 15
  • 80
  • 115
0

Reflection is one option; another is to have your method take a second argument, a generified factory. For instance, guava defines a Function:

public interface Function<F,T> {
    T apply(F input);
}

public static <C extends JSONSerializable> List<C> JSONtoList(
    JSONArray data,
    Function<Object,C> factory)
{
        List<C> list = new ArrayList<C>();
        for (int i = 0; i < data.length(); i++) {
            C instance = factory.apply(data.get(i)) // instead of new
            list.add(instance);
        }   
        return list;
}   

(As I recall, JSONArray.get(int) returns Object, right? If not, replace the factory's F with whatever that method returns.)

The idea here is that the call site will know what C actually is, and it'll be able to define an implementation of Function which, given the JSON array element, returns back a new C instance. Most likely, you'll have this as a private static final anonymous class.

yshavit
  • 42,327
  • 7
  • 87
  • 124