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 поставя всяка екстра в специална карта и не записва как точно искате да бъде парцелирана.

В един момент 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
   }
}

Ако искате да запазите списъка, трябва да създадете клас, който ще може да се сериализира и няма да разширява arraylist, но ще го съдържа вътре.

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

Така че композицията над наследяването, в случай че искате да запазите типа

person Alex Orlov    schedule 02.09.2014
comment
Знаете ли дали Parcelable е над List в този списък за проверка на типа? Бих предпочел класът ми да наследи 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
Но защо intent.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.

можете да погледнете тази връзка. Тя ще изчисти всички съмнения явно кастинг от super клас към подклас

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