ArrayList нельзя привести к пользовательскому классу, расширяющему ArrayList

У меня есть класс, упомянутый ниже:

public class JsonHistoryList extends ArrayList<JsonHistory> implements Serializable{}

Я хочу передать его через намерение, используя

timerService.putExtra(TimerService.ACTIVITY_LIST_ARG, activities);

Но после того, как я его получу (ниже)

JsonHistoryList temp = (JsonHistoryList) intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG);

в моей службе это дает мне исключение:

Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.epstim.captime.jsonmodel.JsonHistoryList

Я не понимаю, почему java не может справиться с этой операцией.

Я изменил свой код в сервисе на:

ArrayList<JsonHistory> temp = (ArrayList<JsonHistory>) intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG);
activities.addAll(temp);

И это сработало.


person Averus    schedule 02.09.2014    source источник
comment
попробуйте очистить проект и запустить его снова.   -  person Tushar Gogna    schedule 02.09.2014
comment
что такое деятельность? ты уверен, что это JsonHistoryList ?   -  person user902383    schedule 02.09.2014
comment
Пожалуйста, напечатайте temp.getClass().toString() и сообщите нам, что это такое.   -  person Stephen C    schedule 02.09.2014
comment
действия - это список JsonHistoryList ??   -  person BatScream    schedule 02.09.2014


Ответы (5)


Внутри андроид помещает все лишнее в специальную карту и не записывает, как именно вы хотите его разделить.

В какой-то момент Android объединит ваши дополнения в пакет, и он сделает это, проверив каждый тип объекта (поскольку, как я уже сказал, он не помнит, как вы этого хотите).

Parcel поддерживает как writeList, так и writeSerializable, и ваш JsonHistoryList также поддерживает оба (список сериализуемых и сам сериализуемый)

Таким образом, парцеллирование Android происходит следующим образом:

for (Object object : extras) {
   //... check for other types here
   } else if (object instanceof List) {
     parcel.writeList(object); // This what happens in your case and will be unparcelled into arraylist
   } else if (object instanceof Serializable) {
     parcel.writeSerializable(object); // What you really want, but percelling never will get here
   }
}

Если вы хотите сохранить список, вам нужно создать класс, который будет сериализуемым и не будет расширять массив, но будет содержать его внутри.

public class SuperJsonHistory implements Serializable {
  private JsonHistoryList yourList;
  ...
}

Итак, композиция вместо наследования, если вы хотите сохранить тип

person Alex Orlov    schedule 02.09.2014
comment
Знаете ли вы, находится ли Parcelable выше списка в этом контрольном списке типов? Я бы предпочел, чтобы мой класс наследовал ArrayList, если я могу! - person rythos42; 09.08.2016
comment
Это просто спасло меня. Спасибо - person Jtvd78; 28.10.2016

Это происходит, если intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG); возвращает объект класса ArrayList<JsonHistory>, а не объект типа JSONHistoryList.

Мы не можем принудительно понизить родительский объект.

Рассмотрим ваш пример, скажем

открытый класс JsonHistoryList расширяет ArrayList, реализует Serializable{ public int someField; // может чем угодно}

Для простоты, если ваш getSerializableExtra(); возвращает new ArrayList<JsonHistory>(), когда вы пытаетесь преобразовать его в JsonHistoryList, он не может выполнить преобразование, потому что значения someField не могут быть определены.

person Anoop    schedule 02.09.2014
comment
Но почему намерение.getSerializableExtra(); возвращает ArrayList, а не JsonHistoryList? - person Averus; 02.09.2014
comment
Я думаю, что ваш activities имеет тип ArrayList<JsonHistory>, и поэтому он возвращает ArrayList - person Anoop; 02.09.2014
comment
в обоих файлах: частные действия JsonHistoryList; во-первых, это активность, а во-вторых, служба - person Averus; 02.09.2014

мы не можем преобразовать объект суперкласса в объект подкласса.

Приведение возможно только в том случае, если объект, который должен быть приведен, проходит отношение IS-A.

вы можете взглянуть на эту ссылку. Это развеет все сомнения явное приведение из супер класс в подкласс

person Vihar    schedule 02.09.2014

Итак, если JsonHistoryList extends ArrayList, то JsonHistoryList — это ArrayList, но ArrayList не обязательно JsonHistoryList. Вы ожидали свой собственный подкласс, но это не то, что вы получили в ответ.

person Sean Owen    schedule 02.09.2014

Я столкнулся с той же проблемой, что и вы, я просто добавляю класс-оболочку, который реализует Serializable:

public class JsonHistoryListWrapper implement Serializable {
    JsonHistoryList jsonHistoryList;

    private JsonHistoryListWrapper(JsonHistoryList jsonHistoryList) {
        this.jsonHistoryList = jsonHistoryList;
    }

    public static JsonHistoryListWrapper wrapper(JsonHistoryList jsonHistoryList) {
        return new JsonHistoryListWrapper(jsonHistoryList);
    }
}
person Seth    schedule 23.06.2019