从InputStream

时间:2016-03-23 06:19:56

标签: java generics android-studio casting

我有一个实例变量HashMap<String, Object> sessions;

我正在尝试从输入流中读取已保存的HashMap<String, Object>实例:

ObjectInputStream is = new ObjectInputStream(fis);
sessions = (HashMap<String, Object>) is.readObject();

然而,在第二行,我收到以下警告:

Unchecked cast: 'java.lang.Object' to 'java.util.HashMap<java.lang.String,java.lang.Object>'

它让我对这个课程进行了整合,而这个课程什么也没做。我尝试将实例变量更改为原始的通用HashMap,并相应地转换为原始HashMap,但每当我尝试将任何内容放入hashmap时,我都会收到未检查的警告,例如:

sessions.put("all", new ArrayList());

产生警告Unchecked call to 'put(K, V)' as a member of raw type 'java.util.HashMap'

我知道这些只是警告,不会在运行时产生问题,但为了正确起见,我怎样才能摆脱所有警告?

我在Android Studio 2.0b7上。

3 个答案:

答案 0 :(得分:2)

编译器无法知道您在运行时从ObjectInputStream读取的类型,因此如果您尝试显式转换它,您将始终获得未经检查的强制转换警告。

唯一的解决方案是添加@SuppressWarnings。最好为未经检查的强制转换添加一个局部变量,因为你可以注释这个,而不是整个方法或类。

@SuppressWarnings("unchecked")
HashMap<String, Object> tmp = (HashMap<String, Object>) input.readObject();
sessions = tmp;

但是,您还应检查您读取的对象instanceof HashMap,以确保未经检查的强制转换至少部分安全(部分,因为您不知道值和键是否真的是您的类型' d expect - 确定你可以迭代密钥以确保它们都是字符串。)

答案 1 :(得分:1)

只需在代码行中添加@SuppressWarnings("unchecked")注释即可。可以将此注释添加到方法或类中。

答案 2 :(得分:1)

通用类型信息未经过序列化,因为它在运行时被type erasure删除了。

反序列化后无法获得准确的通用对象。由于变量级通用信息仅在编译时存在。

如果可能ObjectInputStream提供了一种传递对象类型的方法,那就不是。

只有Generic Class Types才能访问类型信息。使用此hack SpringJackson提供了一种传递类型以从流中读取的方法。

您可以为接收类型的readObject的自定义实现编写实用程序类(使用Spring或Jackson TypeReference或可能是您自己更简单的实现)。在那里你可以检查读取对象是否是正确的类型,如果它是使用传递的类型,它可以被转换为正确的类型。这样您就必须在一个地方禁止警告,并且您将确保正在读取的对象的类型正确。