Obsolete
Status Update
Comments
pl...@gmail.com <pl...@gmail.com> #2
Any object that implements both java.util.List and java.io.Serializable will become
ArrayList after intent.putExtra(EXTRA_TAG,
suchObject)/startActivity(intent)/intent.getSerializableExtra(EXTRA_TAG).
Intent holds its extras in Bundle which in turn is stored in Parcel during
startActivity() call. Deeply in call stack, in Parcel.writeValue() function, check
for List interface is performed before check for Serializable and our object is
stored as List. So, by delegating write operation to Bundle, Intent loses type
information from it's extras.
ArrayList after intent.putExtra(EXTRA_TAG,
suchObject)/startActivity(intent)/intent.getSerializableExtra(EXTRA_TAG).
Intent holds its extras in Bundle which in turn is stored in Parcel during
startActivity() call. Deeply in call stack, in Parcel.writeValue() function, check
for List interface is performed before check for Serializable and our object is
stored as List. So, by delegating write operation to Bundle, Intent loses type
information from it's extras.
ki...@gmail.com <ki...@gmail.com> #3
It would be great if this would be noted in the API documentation.
ru...@gmail.com <ru...@gmail.com> #4
Another one that I had to learn the hard way. Eventually I used a generic container class to save such objects:
public class SerializableHolder implements Serializable {
private Serializable content;
public Serializable get() {
return content;
}
public SerializableHolder(Serializable content) {
this.content = content;
}
}
public class SerializableHolder implements Serializable {
private Serializable content;
public Serializable get() {
return content;
}
public SerializableHolder(Serializable content) {
this.content = content;
}
}
[Deleted User] <[Deleted User]> #5
This seems to be fixed in ICS. I made a class MyList that extends ArrayList<String> and used putSerializable(...) and getSerializable(..) on Gingerbread, Honeycomb, ICS, and JellyBean. Pre-ICS, it's converted into an ArrayList. ICS and later preserve the original type of the serialized object.
bu...@gmail.com <bu...@gmail.com> #6
Disregard my previous comment; it's not fixed in ICS. That was a mistake in my code.
ar...@gmail.com <ar...@gmail.com> #7
Got similar issue with array of enums:
Looking through the code it seems that the problem is that
MyEnum[] data = {value1, value2, value3};
bundle.putSerializable(data); // looks ok, since enum is serializable per se
Bundle just drops the data into its map. At some moment it is actually serialized.
Parcel sees that data is an instance of Object[] (well, it is actually) and calls writeArray to store it instead of writeSerializable (the fact that putSerializable was used to store the value is not recorded anywhere).
When deserializing, Parcel sees that record type is array and creates Object[] to store the data. Then it reads values one by one. And stores it to Bundle's map.
As result, when getSerializable is called in application, returned object type is Object[] instead of MyEnum[]. Which results in ClassCastException.
One possible solution is to store component type name when writing array, then use it when reading.
I have patched the code and tried to build it. Having a (rather reliable) way to reproduce the problem I tested it with patch and no Exception happened.
Looking through the code it seems that the problem is that
MyEnum[] data = {value1, value2, value3};
bundle.putSerializable(data); // looks ok, since enum is serializable per se
Bundle just drops the data into its map. At some moment it is actually serialized.
Parcel sees that data is an instance of Object[] (well, it is actually) and calls writeArray to store it instead of writeSerializable (the fact that putSerializable was used to store the value is not recorded anywhere).
When deserializing, Parcel sees that record type is array and creates Object[] to store the data. Then it reads values one by one. And stores it to Bundle's map.
As result, when getSerializable is called in application, returned object type is Object[] instead of MyEnum[]. Which results in ClassCastException.
One possible solution is to store component type name when writing array, then use it when reading.
I have patched the code and tried to build it. Having a (rather reliable) way to reproduce the problem I tested it with patch and no Exception happened.
fe...@gmail.com <fe...@gmail.com> #8
It's May 2014 and this bug is still there.
java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.app.utils.IndexedList
java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.app.utils.IndexedList
da...@gmail.com <da...@gmail.com> #9
Yup just effected me too :-/
Quite irritatingly little thing.
Quite irritatingly little thing.
en...@google.com <en...@google.com>
p0...@gmail.com <p0...@gmail.com> #10
And It is still there
lg...@gmail.com <lg...@gmail.com> #11
the problem is still present
dw...@sharpmind.de <dw...@sharpmind.de> #12
This problem also exists for any class that implements Map. So if you have a custom class that implements Map or extends from anything that implements Map (for example, HashMap), when you put that class into a Bundle you will always get a HashMap out again.
an...@gmail.com <an...@gmail.com> #13
I am facing the same issue with LinkedList, it is converted to ArrayList after deserialized.
[Deleted User] <[Deleted User]> #14
di...@gmail.com <di...@gmail.com> #15
java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.Object[][]
:(
:(
Description
MyList extends ArrayList<MyNode>.
When I putExtra() MyList into a intent and getExtras().getSerializable() in
the receiving activity, I got a ClassCastException.
Both the caller and callee activities are in the same application.
I found the object can be successfully deserialized, but the class becomes
ArrayList, which is not my own class but its superclass. Is this a bug?
P.S. It seems that there was a similar bug: