Kerage Chan
Kerage Chan

Reputation: 116

Java - casting from unbounded wildcard to string

So, at first I had a line saying :

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

However, since generic type information is erased at runtime, I cannot specify that it is a Set<String>but instead a unbounded wildcard Set<?>. But I need to use this set for String related handling like appending to a JTextArea, so this unbounded wildcard type is not very useful when I require Strings to come out.

So, I tried this

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

This cast gets it from unbounded to a string type (I am sure it will be of Set<String> if the input is a Set) but this isn't very safe is it? I get an error saying I could suppress the unchecked cast but I feel like there may be another way of approaching this. Any ideas?

EDIT: initialised input by serialising from an input stream from a server socket on private LAN ip.

Upvotes: 1

Views: 636

Answers (1)

HTNW
HTNW

Reputation: 29193

You can inspect your object to make sure that it only contains Strings:

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

You'll still have to suppress the warning. This is safer than your original, because if the set contains only Strings (or is empty), it can usually be treated as a Set<String>. However, it is still rather unsafe, because, for example, you may have deserialized an empty EnumSet. An EnumSet needs to cast its elements to Enums to get their ordinal()s, but a String can't do that! You may want to copy the set into your own set first:

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

This only iterates the elements input, which is less likely to blow up, and guards you from giving elements to input that it can't handle. Note that it's not just inserting that is unsafe, simply checking whether an item of the wrong type is in the set could blow it up.

Upvotes: 1

Related Questions