How can I specify that I want any object that implements the A interface to be allowed inside of the List in a type-safe manner? I want to be able to invoke a given method of A over all of the objects, regarding what Class type they are.
public interface A (){}
List<? extends A> myList = new ArrayList<? extends A>();
I am getting: Cannot instantiate the type ArrayList<? extends A>
If I leave the generic off of the instantiation side it works fine, but I have to specify @SuppressWarnings({ "rawtypes", "unchecked" }) to make the compiler hush up about the warnings.
To see why it doesn’t make sense to instantiate a
new ArrayList<? extends A>(), in fact we can equivalently create anew ArrayList<B>()with any arbitrary class or interfaceB(even one that is not related to any of your objects) that implementsA, and the resulting created ArrayList can be safely assigned to a variable of typeArrayList<? extends A>. Then you might wonder, oh, this is stupid, because the objects I want to put into it are not of class B, so how can this be the same? But it is the same, because you cannot put anything into a reference of typeSomething<? extends A>anyway. This is why it doesn’t make sense to create anew ArrayList<? extends A>().That’s exactly what
ArrayList<A>is. It allows all instances ofA(of course all objects that implementAare instances ofA) and you can use any methods ofAon them. Something like this is what you want:Something like
List<? extends A>is only used in cases when you will get a List object from some other code, and you don’t know (or care) what exactly is the generic parameter they created it with. (In such a case you cannot put objects into the List.) This is completely different from your case here, where you are creating the List object, so you decide and therefore know exactly what generic parameter is used.