2009-10-22 72 views
5
public Configuration(Node node, File file) { 
    HashMap<String, String> conf = (HashMap<String, String>) SerializationUtils.deserialize(new FileInputStream(file)); 
} 

我明白为什么这给出了一个不安全的投警告,但什么是最好的/接受的方式安全地做到这一点?有什么好方法吗?不安全通用铸在集合

回答

2

您不能以完全类型安全的方式仅使用Java语言来处理这种情况。

因为这一点是必须要反复做,你不能真正周围的东西,我建议使用genreic方法和阅读并投通用对象:

@SuppressWarnings("unchecked") 
public static <T> T readObject(
    ObjectInputStream in 
) throws IOException, ClassNotFoundException { 
    return (T)in.readObject(); 
} 

不过,我建议你通常不会使用这种方法来抑制有效的警告。

+0

这就是我害怕的;只是希望我错过了一些东西:/ – 2009-10-22 21:12:29

+0

这是一个有效的警告,只有在语言特征设计破碎的情况下! – 2009-10-22 23:29:24

+1

如果不是用于类型擦除,我们将无法对这些对象进行反序列化。我认为这是一场胜利。 – 2009-10-22 23:53:49

2

有没有真正要检查这样做正确,因为编译时类型信息的任何方式(即String)不可在运行时(即当施放实际发生),整个过程被称为擦除 。我认为,最好的办法是你自己把你的反序列化集合将向您介绍一些定制的“检查”:

Map<?,?> conf = deserialize(rsrc); 
Map<String, String> checked = checkMap(conf, String.class, String.class); 
//can use checked freely 

其中:

@SuppressWarnings("unchecked") 
public static <K, V> Map<K,V> checkMap(Map<?,?> map, Class<? extends K> k, Class<? extends V> v) { 
    for (Map.Entry<?, ?> e : map) { 
     k.cast(e.getKey()); //will throw ClassCastException 
     v.cast(e.getValue()); 
    } 
    return (Map<K,V>) map; //unchecked 
} 
+0

任何人都在意澄清为什么一个完全有效和正确的答案已被低估?是否因为*我*低估了一个无效和不正确的答案? – 2009-10-22 21:27:50

+0

我不是downvoter,但我可以看到,这可能不适用于多线程访问的情况。一个线程运行检查器,另一个线程使用原始引用在检查之后插入“错误”类型。 Boom,ClassCastException。 – 2009-10-22 21:42:03

+0

@Steven - 我不认为*“在多线程环境中可能不安全”*必然是这种“检查”方法的错误。我为自己的回答添加了更多细节。该方法根本没有被设计成以这种方式工作,并且因此可以被记录为 – 2009-10-23 07:02:54

1

要建立在刚才的答复,我通常会去远一点当禁止警告时。我将注释放在局部变量而不是方法上,以减少抑制的范围。这意味着如果有人在后来增加方法,就不会有无意的压制。它确实增加了另一行代码,但我认为这种折衷是值得的。

public static <T> T readObject(
    ObjectInputStream in 
) throws IOException, ClassNotFoundException { 
    @SuppressWarnings("unchecked") 
    T val = (T)in.readObject(); 
    return val; 
} 

可惜你不能注释添加到一个表达式(至少目前还没有)。

+0

我倾向于将注释放在该方法上,因为该方法的全部要点是压制警告。 – 2009-10-22 23:11:58