Skip to main content

Problem with Generic types and ArrayList

3 replies [Last post]
beatbang
Offline
Joined: 2007-11-03

Hi.
I have a programme where I have the classes Client and Provider that extends People. When I do a search in the data base I obtain an ArrayList whith objects Client or Provider, it dependes on the case. After this operation to obtain some data I have to transfer this Arraylist to a method that works directly with objets People.
I use generic types in the array and in the method, but when it cames the time to make the compilation, i obtain an error.
In code:

ArrayList clients = new ArrayList();
//Add objects Client to clients.
ArrayList providers = new ArrayList();
//Add objects Provider to providers

//I have this method
public void usePeople(ArrayList peoples) { }

//And I call the method
usePeople(clients);
usePeople(providers);

I don't why it doesnt' work, what is wrong with the procedure I'm following? what can I do instead of that procedure? The idea is not to duplicate the method, making one for Client and another for Provider, because I work there with the data take it only from People, and I dont want to use ArrayList when I add the objects Client and Provider because I would have to do unnecesary casting.

Thanks for you help.
£µ¢ianø

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
tarbo
Offline
Joined: 2006-12-18

Using the following method signature should solve this:
[code]public void usePeople(ArrayList peoples)[/code]
Contrary to subclassing, generics do not support this kind of polymorphism. Consider what would happen if the compiler did accept the code. I could add an instance of People to the list and effectively break the generics (because suddenly a list of Client or Provider holds an instance of superclass People).

Generics are a little tricky to get your mind around where a few rules of thumb can really help you out. I keep these (incomplete) helper rules in mind, and they help me out of every bind or quirk I ever found myself in.

[i]<? extends A> means read access.[/i] You are assured that the types in the collection are at least of type A, but can be any subclass. The result is that you can retrieve elements as type A, but you can't add anything because you don't know what the exact type is. It could be A, or it could be any subclass of A.

[i]<? super A> means write access.[/i] You're assured the maximum restriction is type A. I can add an Object, if I want to, or I can add an A. I can even add a subclass of A. But when I try to retrieve anything, the best the compiler can guarantee me is that the object is an Object.

[i]<A>[/i] is maximum restriction from a generic point of view, giving both read as write access, but consequently being the strictest in what it accepts. Only use this when you require both (which is rare, in my experience). It's probably not what you want or need.

Hope this is helpful,
Jonathan

swv
Offline
Joined: 2007-05-28

wow what a great reply. I am bookmarking this one.

tarbo
Offline
Joined: 2006-12-18

I've made an error, though. :(

> means write access. You're assured the maximum restriction
> is type A. I can add an Object, if I want to, or I can add an A. I can even
> add a subclass of A. But when I try to retrieve anything, the best the
> compiler can guarantee me is that the object is an Object.

It should not say "I can add an Object"; it should say that I can add an object of type A or any subclass, because I'm guaranteed that the type restriction is at most A.

*sigh* Errare humanum est.

Cheers,
Jonathan