【问题标题】:serialize/deserialize a LinkedHashMap (android) java序列化/反序列化 LinkedHashMap (android) java
【发布时间】:2011-02-22 20:06:12
【问题描述】:

所以我想将 LinkedHashMap 传递给意图。

//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 的替代方案
  • AFAIK ...这个答案与这个实际上是关于泛型类型的问题无关。
  • 您遇到什么运行时错误?请包括堆栈跟踪。

标签: java android serialization linkedhashmap


【解决方案1】:

这里问题的根源是您试图将类型转换为泛型类型。如果没有不安全/未经检查的类型转换,这将无法完成。

泛型类型的运行时类型是原始类型;即类型参数的实际类型未知的类型。在这种情况下,运行时类型将为LinkedHashMap&lt;?, ?&gt;。这不能安全地类型转换为 LinkedMashMap&lt;String, String&gt;,因为运行时系统无法知道所有键和值实际上都是 String 实例。

你有两个选择:

  • 您可以添加一个注释来告诉编译器“关闭”未经检查的强制转换。这有点冒险。如果由于某种原因其中一个键或值实际上不是字符串,您的应用程序可能稍后会在一个完全意想不到的地方获得ClassCastException;例如在迭代键或分配 get 的结果时。

  • 您可以手动将反序列化的Map&lt;?, ?&gt; 复制到新的LinkedMashMap&lt;String, String&gt; 中,将每个键和值显式转换为String

更新

显然,运行时异常的真正原因(与“不安全的类型转换”编译错误不同)是 Android 在意图之间传递 serializedExtra 作为常规 HashMap 而不是使用您的 Map 类假如。此处对此进行了描述:

正如问答所述,没有简单的解决方法。如果要传递保留键顺序的映射,则必须将映射转换为对数组并传递它。另一方面,您将需要从传递的数组中重建地图。

【讨论】:

  • 关于注释它告诉编译关闭但不能解决问题。我收到警告而不是错误。我得到的错误是在运行时,无法真正理解为什么。这是 utils.LinkedHashMap.java 中的一个类异常,第二个答案没有再次解决问题。问题是 LinkedHashMap 由于某种原因无法序列化但是非常感谢您的回答和编写它所花费的时间
  • 您的问题是关于编译器警告的,而我的回答告诉您两种处理该编译器警告的方法。如果您还遇到运行时错误,您应该在问题中这么说......并且您还应该提供堆栈跟踪。不像 Jon Skeet,我无法读懂你的想法。
  • 我很抱歉。你说得对,我现在找这个太久了。再次抱歉,我刚刚编辑了我的第一篇文章
  • 实际上,这里问题的根源在于对`getIntent().getSerializableExtra("db")`的调用返回了HashMap而不是LinkedHashMap。这与 Harmony 无关,它是 Android 的特性。
【解决方案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 中没有。 (当然,这是一个错误。)