3

I have a simple class structure:

class BaseModel {}

class Performer extends BaseModel {}

And I have a collection of Performers:

ArrayList<Performer> list = loadPerformerList();

Why can't I do this?

functionThatNeedsArrayOfBase( (ArrayList<BaseModel>)list );

Or, how can I do that, properly?

Josh
  • 12,448
  • 10
  • 74
  • 118

5 Answers5

10

A collection of child is not a collection of base. Otherwise you could add base objects to your child collection, breaking the assumption (same the other way around as well).

You could specify the parameter to your function as a list containing derivatives of base:

void functionThatNeedsArrayOfBase(ArrayList<? extends BaseModel> list) {
  //...
}

Then you can just pass list without casting

Attila
  • 28,265
  • 3
  • 46
  • 55
2

Try this instead: <? extends BaseModel>, it doesn't say which subclass of BaseModel just that it is one specific. See also <? super BaseModel>depending on your needs.

Mattias Isegran Bergander
  • 11,811
  • 2
  • 41
  • 49
1

list is an ArrayList of Performer(s). If java allowed you to cast that to ArrayList<BaseModel>, even the list at that moment only contained BaseModel(s) what would happen when one adds an Performer to the list that is not a BaseModel? We lose type safety if we allow that.

esej
  • 3,059
  • 1
  • 18
  • 22
1

The problem is the type safety of the ArrayList. You can find several more detailed explanations on this StackOverflow Post. In short, the way around this problem is to have the method accept classes of type <? extends/super Performer>.

Community
  • 1
  • 1
Toaster
  • 1,911
  • 2
  • 23
  • 43
1

The reason this does not work, is that it would allow functionThatNeedsAnArrayOfBase() to add a different BaseModel subclass to the list and corrupt the original list reference.

A good example with further explanation is this stack overflow question.

Another good reference is Josh Bloch's coverage of Generics in Essential Java.

Community
  • 1
  • 1
Timothy055
  • 56
  • 1
  • 4