weakwire weakwire - 1 year ago 93
Java Question

serialize/deserialize a LinkedHashMap (android) java

So i want to pass a LinkedHashMap to an intent.

Intent singlechannel = new Intent(getBaseContext(),singlechannel.class);
singlechannel.putExtra("db",shows1);//perase to

LinkedHashMap<String,String> db = new LinkedHashMap<String,String>();
db=(LinkedHashMap<String,String>) getIntent().getSerializableExtra("db");

This one Worked Like a charm with HashMap.
But with LinkedHashMap i got a problem i got a runtime error here

db=(LinkedHashMap<String,String>) getIntent().getSerializableExtra("db");

I get no error with HashMap.

I also got a warning "Type safety: Unchecked cast from Serializable to LinkedHashMap"
But i had this warning with HashMap too.
Any ideas.Any help is much appreciated

Also I just saw this.

Answer Source

The root of the problem here is that you are trying to type cast to a generic type. This cannot be done without an unsafe/unchecked type cast.

The runtime types of generic types are raw types; i.e. types in which the actual types of the type parameters are not known. In this case the runtime type will be LinkedHashMap<?, ?>. This cannot be safely typecast to LinkedMashMap<String, String> because the runtime system has no way of knowing that all of the keys and values are actually String instances.

You have two options:

  • You could add an annotation to tell the compiler to "shut up" about the unchecked cast. This is a bit risky. If for some reason one of the keys or values is not actually a String, your application may later get a ClassCastException at a totally unexpected place; e.g. while iterating the keys or assigning the result of a get.

  • You could manually copy the deserialised Map<?, ?> into a new LinkedMashMap<String, String>, explicitly casting each key and value to String.


Apparently the real cause of the runtime exception (as distinct from the "unsafe typecast" compilation error) is that Android is passing the serializedExtra between intents as a regular HashMap rather than using the Map class that you provided. This is described here:

As that Q&A explains, there is no simple workaround. If you want to pass a map preserving the key order, will have to convert the map to an array of pairs and pass that. On the other end, you will then need to reconstruct the map from the passed array.