upcast from List<subclass> to List<superclass> via List<?>

I have a class A and a class B extends A

In another class C I have a field

private List<B> listB;

Now, for some unusual reason, I have to implement this method in C

public List<A> getList();

I tried to do so by forcing an upcast of listB field to List<A> via a List<?> cast:

public List<A> getList(){
    return (List<A>)(List<?>)listB;
}

Clients should do

List<A> list = getList();
for(A a:list){
    //do something with a
}

I did some test and it seems work correctly, but honestly I am not sure of the all possible implications.

Is this solution correct? And Is it the best solution?

Thanks for your answers.

Answers


No, this isn't safe. The client shouldn't be able to do

List<A> list = getList();

because otherwise they could write

list.add(new C()); // Where C extends A

Then the original code which knows about the list as a List<B> will have problems when it tries to use it, assuming that every element is compatible with B.

You could either wrap the original list to make it read-only, effectively - or make getList return a List<? extends A>, which means that clients won't be able to add items to it anyway.


The problem with this is that clients can, unwittingly, insert A objects in what is actually a list of more specific B objects only:

c.getList().add(new A());

This will cause all kinds of breakage when your code tries to take an object from the list assuming that it's a B, but it isn't.

If your only goal is to let the client iterate over the list, it is better to hand out an Iterable<A> instead:

public Iterable<A> getAs() { return this.theListOfAs; }

Through this Iterable, one can only inspect and remove elements, but not add them.

If you want to disable removal as well, wrap the List's Iterable in your own implementation, throwing UnsupportedOperationException when remove() is called.


Need Your Help

String that contains $1

python string subprocess

I have a script that scrolls through all the folders of unzipped files and get information of the contents.

How to save sqlite db file of another android application.?

java android android-sqlite axis2

i developed application for sales force in our company.most of them do sales in rural areas and more times no signal for those areas.then they tell us they synch their sales to server.but more sales