在安卓Java中如何序列化/反序列化一个LinkedHashMap?

5

我想把一个LinkedHashMap传递给Intent。

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

//GET THE MAP
LinkedHashMap<String,String> db = new LinkedHashMap<String,String>();   
db=(LinkedHashMap<String,String>) getIntent().getSerializableExtra("db");

这个在使用HashMap时非常有效。 但是在使用LinkedHashMap时,我遇到了一个运行时错误。
  db=(LinkedHashMap<String,String>) getIntent().getSerializableExtra("db");

使用HashMap时没有出现错误。

我也遇到了一个警告“类型安全性:从Serializable到LinkedHashMap的未检查强制类型转换”,但是我在使用HashMap时也遇到了这个警告。有什么想法吗?任何帮助都将不胜感激。

此外,我刚刚看到了这个链接。 https://issues.apache.org/jira/browse/HARMONY-6498


请查看我对你原问题的回答,以获取LinkedListHashMap的替代方案。 - mdma
据我所知,那个答案与这个问题无关,实际上是关于通用类型的。 - Stephen C
你遇到了什么运行时错误?请包含堆栈跟踪。 - Stephen C
请看此链接:https://dev59.com/WWct5IYBdhLWcg3wKqUd#12305459 - David Wasser
请参见https://dev59.com/51HTa4cB1Zd3GeqPU9Xa#38960732。 - David Wasser
2个回答

4
问题的根源在于您试图将类型强制转换为通用类型。这无法在没有不安全/未经检查的类型转换的情况下完成。
通用类型的运行时类型是原始类型;即类型参数的实际类型未知的类型。在这种情况下,运行时类型将为 LinkedHashMap。这不能安全地转换为 LinkedHashMap,因为运行时系统无法知道所有键和值实际上都是 String 实例。
您有两个选择:
  • 你可以添加注释告诉编译器“闭嘴”,不要再提未检查的转换。这有点冒险。如果某个键或值不是String类型,你的应用程序可能会在完全意料不到的地方(例如,在迭代键或分配get的结果时)稍后出现ClassCastException异常。

  • 你可以手动将反序列化的Map<?, ?>复制到一个新的LinkedMashMap<String, String>中,明确将每个键和值强制转换为String。

更新

显然,运行时异常的真正原因(与“不安全类型转换”编译错误不同)是Android将serializedExtra作为常规HashMap传递给意图,而不是使用你提供的Map类。这在这里描述:

如同该问答所解释的那样,没有简单的解决方法。如果你想传递一个保留键顺序的映射,必须将该映射转换为一组成对的数组并传递。在另一端,您需要从传递的数组中重建映射。

关于注释,它告诉编译器保持安静,但并没有解决问题。我得到了一个警告而不是错误。我在运行时得到的错误,真的不太明白为什么。这是 utils.LinkedHashMap.java 中的类异常。 第二个答案也没有解决问题。 问题是 LinkedHashMap 由于某种原因无法序列化。 非常感谢您的回答和撰写所花费的时间。 - weakwire
1
你的问题涉及编译器警告,我的答案告诉你两种处理编译器警告的方法。如果你还遇到运行时错误,在问题中应该表明...而且你还应该提供堆栈跟踪信息。和Jon Skeet不同,我不能读懂你的思想。 - Stephen C
非常抱歉,你是对的,我已经看了很久了。再次道歉,我刚刚编辑了我的第一篇帖子。 - weakwire
实际上,问题的根源在于对 getIntent().getSerializableExtra("db") 的调用返回了一个 HashMap 而不是 LinkedHashMap。 这与 Harmony 没有任何关系,这只是 Android 的一种特殊性。 - David Wasser

2
LinkedHashMap实现了Map接口,以下是源代码中的定义:
public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>

以下测试工作正常,因此我认为你遇到的问题与LinkedHashMap无关。
Map<String, String> map = new LinkedHashMap<String, String>();
        map.put("1", "one");
        FileOutputStream fos = new FileOutputStream("c://map.ser");
        ObjectOutputStream out = new ObjectOutputStream(fos);
        out.writeObject(map);
        out.close();


        FileInputStream fin = new FileInputStream("c://map.ser");
        ObjectInputStream in = new ObjectInputStream(fin);
        Map<String, String> map2 = (Map<String, String>) in.readObject();
        System.out.println(map2); 

显然在某些版本的Harmony中不起作用。(当然,这是一个bug。) - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接