Java adding to a unknown type generic list

35,384

Solution 1

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.

Solution 2

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.

Solution 3

You could just use ArrayList<Object>, to which you can add() anything.

Share:
35,384
ars265
Author by

ars265

Updated on September 01, 2020

Comments

  • ars265
    ars265 over 3 years

    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();