通过JSON加载HashMap失败求助(基于GSON实现)
Let's break down why your loading code is failing and how to fix it:
The Root Cause
When you save the perks map, GSON serializes the Perk keys (I’m assuming Perk is an enum here, given the uppercase constant like DAMAGE_AMPLIFIER) into their string names. But when loading, your current approach converts the JsonElement to a raw string and parses it without telling GSON that the map keys should be converted back to Perk instances. Without specifying the generic type, GSON defaults to parsing keys as String, which can’t be cast to Perk—hence the failure.
The Fix
You need to explicitly tell GSON to parse the JSON into a HashMap<Perk, Boolean> by using a TypeToken, which captures the generic type information erased at runtime. Here’s how to adjust your code:
1. Update the Loading Code
Instead of converting the JsonElement to a string first (unnecessary and type-context-losing), pass the JsonElement directly to your jsonToMap method:
if (reader.has("perks")) { jsonToMap(reader.get("perks"), player); }
2. Modify the jsonToMap Method
Update the method to use TypeToken to define the exact map type for GSON:
public static void jsonToMap(JsonElement perksElement, Player player) throws JsonParseException { Gson gson = new Gson(); // Capture the generic type HashMap<Perk, Boolean> using TypeToken Type perkMapType = new TypeToken<HashMap<Perk, Boolean>>() {}.getType(); HashMap<Perk, Boolean> parsedPerks = gson.fromJson(perksElement, perkMapType); // Assign the parsed map to your player object player.perks = parsedPerks; // Use a setter method instead if you have one (better encapsulation): // player.setPerks(parsedPerks); }
If You Must Keep the String Parameter
If you can’t change the jsonToMap method’s parameter type from String, you can still make it work with the same TypeToken approach:
public static void jsonToMap(String jsonString, Player player) throws JsonParseException { Gson gson = new Gson(); Type perkMapType = new TypeToken<HashMap<Perk, Boolean>>() {}.getType(); HashMap<Perk, Boolean> parsedPerks = gson.fromJson(jsonString, perkMapType); player.perks = parsedPerks; }
Why This Works
The TypeToken lets GSON retain the generic type details (Perk as key, Boolean as value) that Java strips at compile time. This tells GSON to parse the JSON’s string keys back into Perk enum instances (matching their name() values) instead of leaving them as raw strings.
Quick Check
Ensure your Perk enum is properly defined—GSON handles enums out of the box using their name() for serialization and valueOf() for deserialization, so no custom code is needed here.
内容的提问来源于stack exchange,提问作者Taylan Selvi

