Java - 从无界通配符转换为字符串

时间:2018-02-13 15:08:47

标签: java generics set instanceof unbounded-wildcard

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

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

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

所以,我试过这个

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

此演员表从无界限到字符串类型(如果输入是Set<String>,我相信它会是Set)但是这不是很安全吗?我得到一个错误,说我可以压制未经检查的演员,但我觉得可能有另一种方法来接近这个。有什么想法吗?

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

1 个答案:

答案 0 :(得分:1)

您可以检查对象以确保它只包含String s:

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

你还是要压制警告。这比原始版本更安全,因为如果集合仅包含String s(或为空),则通常可被视为Set<String>。但是,它仍然相当不安全,因为,例如,您可能已反序列化空EnumSetEnumSet需要将其元素投放到Enum以获取ordinal() s,但String无法执行此操作!您可能希望首先将集合复制到您自己的集合中:

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

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