2012-06-06 4 views
3

У меня есть простая структура класса:Java - Литая ArrayList Up Hierarchy

class BaseModel {}

class Performer extends BaseModel {}

И у меня есть коллекция Performer с:

ArrayList<Performer> list = loadPerformerList();

Почему может Я так делаю?

functionThatNeedsArrayOfBase((ArrayList<BaseModel>)list);

Или, как я могу сделать это, правильно?

ответ

10

Коллекция детей не Коллекция базы. В противном случае вы можете добавить базовые объекты в свою дочернюю коллекцию, нарушив предположение (так же, как и наоборот).

Вы можете задать параметр для вашей функции в виде списка, содержащего производные основания:

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

Тогда вы можете просто пройти list без литья

1

Список: ArrayList исполнителей (исполнителей). Если java разрешил вам наложить это на ArrayList<BaseModel>, даже список в тот момент содержит только BaseModel (ы), что произойдет, когда вы добавите исполнителя в список, который не является BaseModel? Если мы допустим это, мы потеряем безопасность.

2

Попробуйте вместо этого: <? extends BaseModel>, это не говорит который является подклассом BaseModel только для того, чтобы он был конкретным. См. Также <? super BaseModel> в зависимости от ваших потребностей.

1

Проблема заключается в безопасности типа ArrayList. Вы можете найти несколько более подробных объяснений по этому вопросу StackOverflow Post. Короче говоря, путь вокруг этой проблемы заключается в том, чтобы метод принимал классы типа <? extends/super Performer>.

1

Причина, по которой это не работает, заключается в том, что это позволит functionThatNeedsAnArrayOfBase() добавить в список другой подкласс BaseModel и испортить исходный список ссылок.

Хороший пример с дальнейшим объяснением - this проблема с переполнением стека.

Еще одна хорошая рекомендация - охват Джошем Блохом дженериков в Essential Java.