bluecricket
bluecricket

Reputation: 2042

ClassCastException when using String[]

I am using ObjectMapper to convert a JSON String to a Map but I get ClassCastException when trying to retrieve a value:

Map<String,String[]> args = objectMapper.readValue(jsonString, HashMap.class);
String[] array = args.get(paramName);

then doing

String x = array[0];

gives

java.lang.ClassCastException: java.util.ArrayList cannot be cast to [Ljava.lang.String

How can this be when I clearly specify String[] and not ArrayList, and when the second line doesn't cause any errors...

Upvotes: 3

Views: 1060

Answers (3)

Marko Topolnik
Marko Topolnik

Reputation: 200296

Your diagnosis is incorrect. The line that throws the ClassCastException is

String[] array = args.get(paramName);

and not the later array access. The reason for the error to occur at this line is, I believe, obvious: the map value simply isn't an array, but is in fact an ArrayList.

Upvotes: 0

Mason Bryant
Mason Bryant

Reputation: 1392

The object mapper does not obey (in fact cannot) the parameterized type information you used. It only knows about the class you are passing in as an argument. You'd be much better off using the generic type.

What you are actually getting back is:

Map<Object, Object> args = objectMapper.readValue(jsonString, HashMap.class);

I recommend changing your code to use something that for your arguments and then doing class casts and checking accordingly.

For example:

Map<Object, Object> args = new LinkedHashMap<Object, Object>();
Object value = args.get("foo");
String x;
if (value instanceof String[]) {
    String[] array = (String[])value;
    x = array[0];
} else if(value instanceof List) {
    List<Object> list = (List<Object>) value;
    x = String.valueOf(list.get(0));
} else {
    //error handling
}
...

Upvotes: 0

Philipp Reichart
Philipp Reichart

Reputation: 20961

HashMap.class is the only information available to objectMapper at runtime.

It doesn't know that you declared a Map<String, String[]> on the left-hand side, so it does what most JSON mappers would do: It assumes you want a 1:1 map-based representation of the JSON which results in a Map<String, ArrayList<String>>.

Just use

List<String> list = args.get(paramName);
String x = list.get(0);

instead of String[] array and array[0].

Better yet, map your JSON into actual model classes, not a HashMap.

Upvotes: 2

Related Questions