Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java adding to a unknown type generic list

I've come into something I haven't come across before in Java and that is, I need to create a new instance of say the ArrayList class at runtime without assigning a known type then add data to the list. It sounds a bit vague so here is an example:

Class<?> c = i.getClass();

Constructor<?> con = ArrayList.class.getConstructor();
ArrayList<?> al = (ArrayList<?>)con.newInstance();

al.add("something");

Now the reason I'm doing this versus just using generics is because generics are already being used heavily and the "i" variable in this example would be given to use as type "?". I would really rather not throw in another generic as this would cause more work for the user and would be much less flexible in the end design. Is there any way to use something like below (Note: what is below doesn't work). Anyone have ideas?

ArrayList<c> al = (ArrayList<c>)con.newInstance();
like image 739
ars265 Avatar asked Jun 29 '11 02:06

ars265


People also ask

How do you add an object to a generic list in Java?

You can get and insert the elements of a generic List like this: List<String> list = new ArrayList<String>; String string1 = "a string"; list. add(string1); String string2 = list. get(0);

How do I restrict a generic type in Java?

Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.


2 Answers

You can't add objects in a Collection defined using wildcards generics. This thread might help you.

Indeed you are creating a collection that is, yes, the super type of every collection, and as such, can be assigned to any collection of generics; but it's too generic to allow any kind of add operation as there is no way the compiler can check the type of what you're adding. And that's exactly what generics are meant to : type checking.

I suggest you read the thread and see that it also apply to what you wanna do.

Your collection is just too generic to allow anything to be added in. The problem has nothing to do with the right hand side of the asignment (using a singleton or reflection), it's in the left hand side declaration type using wildcards.

like image 96
Snicolas Avatar answered Sep 23 '22 03:09

Snicolas


If I get what you mean, you have a class C, which is unknown at compile time, and you want to create an ArrayList<C>, in a type safe way. This is possible:

Class<?> c = ...;
ArrayList<?> al = listOf(c);

static <T> ArrayList<T> listOf(Class<T> clazz)
{
    return new ArrayList<T>();
}

This is the theoretically correct way of doing it. But who cares. We all know about type erasure, and there's no chance Java will drop type erasure and add runtime type for type parameters. So you can just use raw types and cast freely, as long as you know what you are doing.

like image 43
irreputable Avatar answered Sep 22 '22 03:09

irreputable