1

所以,起初我有一句话说:

Object input = .... //some come code initialising it
if(input instanceof Set<String>) {
    doSomething(input);
}

但是,由于泛型类型信息在运行时被删除,我不能指定它是 aSet<String>而是 unbounded wildcard Set<?>。但是我需要将此集合用于与字符串相关的处理,例如附加到 JTextArea,因此当我需要字符串出来时,这种无界通配符类型不是很有用。

所以,我试过这个

Object input = .... //some come code initialising it
if(input instanceof Set<?>) {
    doSomething((Set<String>) input);
}

Set<String>这种转换将它从无界转换为字符串类型(如果输入是 a ,我相信它会是Set)但这不是很安全,是吗?我收到一条错误消息,说我可以压制未经检查的演员表,但我觉得可能有另一种方法可以解决这个问题。有任何想法吗?

编辑:input通过从私有 LAN ip 上的服务器套接字的输入流序列化来初始化。

4

1 回答 1

1

您可以检查您的对象以确保它仅包含Strings:

if(input instanceof Set<?> && ((Set<?>)input).stream().allMatch(x -> x instanceof String)) {
    doSomething((Set<String>)input);
}

您仍然必须抑制警告。这比你原来的更安全,因为如果集合只包含Strings (或为空),它通常可以被视为 a Set<String>。但是,它仍然相当不安全,因为例如,您可能已经反序列化了一个空的EnumSet. AnEnumSet需要将其元素转换为Enums 以获得他们ordinal()的 s,但 aString不能这样做!您可能需要先将集合复制到您自己的集合中:

if(...) {
    Set<String> input2 = new HashSet<>();
    input2.addAll((Set<String>)input);
    doSomething(input2);
}

这只会迭代input不太可能爆炸的元素,并防止您将元素提供给input它无法处理的元素。请注意,不只是插入是不安全的,简单地检查集合中是否有错误类型的项目可能会炸毁它。

于 2018-02-13T15:21:01.440 回答