0
  1. Create a (String, Object) hashMap and put values of different types.
  2. Serialize the hashmap into a json string and convert back into a hashmap of (String, String)

When I try to get the value of key "key2", it will throw an exception saying "Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String".

Is there a good way to explain this? Does it mean even though I have a (String, String) map, the value in it is not necessary String?

Apologize for any confusion. Let me know if something is not clear.

Map<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", 99);
map.put("key3", new Date());


JsonUtil jsonUtil = new JsonUtil();

String s = jsonUtil.toJson(map);

HashMap<String, String> newMap = jsonUtil.fromJson(s, HashMap.class);

String value = newMap.get("key2");
3
  • 6
    Making your entire post bold makes the boldness pointless. Commented Feb 16, 2017 at 4:18
  • 2
    I would suggest turning on all compiler warnings (and do not suppress them with annotations). It is likely one of those warnings would have told you this was going to happen. Commented Feb 16, 2017 at 5:35
  • @VGR Possibly, but this is a weird edge case where the argument HashMap.class is required as a type literal(*) but can't take generic parameters. Commented Feb 16, 2017 at 7:46

3 Answers 3

2

In map, the value of key "key2" is 99, which is an integer. The exception is possibly being thrown in the second to last line, not the last line. I'm not entirely sure why you are serializing and then immediately deserializing, but if you just want 99 as a String like "99", the way to do this would be:

String value = String.valueOf(map.get("key2"));

The serializing and deserializing would not be necessary in this case.

Better yet, if you just want a Map<String, String> for the whole time, you can do something like this:

Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", String.valueOf(99));
map.put(new Date().toString());
Sign up to request clarification or add additional context in comments.

2 Comments

The exception is absolutely being thrown on the last line, at the implicit cast from Integer to String.
I guess my question is, how come an Integer exist in a <String, String> map?
1

When you call fromJson(s, HashMap.class), you're not providing any generic type information to the decoder--all it sees is HashMap, and the implicit return type from that call is HashMap<?,?>. JSON can assume string keys, and the decoder is doing its best to decode objects into their "native" representations, so when you tell the compiler that all of the keys and values are strings, there's a mismatch.

If you specify which JsonUtil is involved, we may be able to provide a more specific approach; otherwise, you could use something like a stream transform to convert every value to v.toString().

2 Comments

I guess my question is, why can I get a Integer object out of a <String, String> map? Why it did not fail on this line HashMap<String, String> newMap = jsonUtil.fromJson(s, HashMap.class); when it tries to assign a <String, Object> map to a <String, String> map?
@xyqshi You need to read about "type erasure". At runtime, there is only HashMap.
0

String value = newMap.get("key2");

In this line you are getting the value of key2 in hashMap and then assigning it to a String type variable value which is invalid. Because the value of key2 is Integer type, you cannot do this directly. You can put this value in `Integer type variable. as bellow:

int value = newMap.get("key2");

Or if you want a generic solution so that you can assign any type of variable into value then you can declare it as Object type. as bellow:

Object value = newMap.get("key2");

2 Comments

Does it mean given a <String, String> map, I still need to verify the types of its elements?
Declaring a map with <String, String> means this map will accept Key and Value of String type data. If the map is declared so, you don't need to verify the element's value's type because it can only be String.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.