繁体   English   中英

反序列化集合时不安全的通用转换

[英]Unsafe generic cast when deserializing a Collection

public Configuration(Node node, File file) {
    HashMap<String, String> conf = (HashMap<String, String>) SerializationUtils.deserialize(new FileInputStream(file));
}

我理解为什么这会给出不安全的演员警告,但是安全地做到这一点的最佳/可接受方式是什么? 有什么好办法吗?

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

因为这是必须重复完成的事情,你无法真正解决它,我建议使用genreic方法来读取和转换泛型对象:

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

但是,我建议您通常不使用此类方法来抑制有效警告。

实际上没有任何方法可以正确执行此操作,因为您要检查的编译时类型信息(即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 
}

为了建立早期的答案,我通常会在抑制警告时更进一步。 我将注释放在局部变量而不是方法上,以减少抑制的范围。 这意味着如果有人在以后增加该方法,则不会有无意的抑制。 它确实添加了另一行代码,但我认为权衡是值得的。

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

遗憾的是,您无法在表达式中添加注释(至少尚未添加)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM