Gson LinkedTree 映射无法转换为 InformativeItemProvider

Gson LinkedTree map cannot be casted to InformativeItemProvider

开始:我知道这个错误很常见,而且看起来可能重复。
但它不是,阅读代码,我会解释我的错误。

在这种情况下,我的 Minecraft 插件存在 3 个重要 classes,但只有它 JSONConfig 所有的魔法都在发生:

JSONConfig.java

public class JSONConfig {
    private String Path;
    private Map<String,Object> config;
    private File pathfile;
    public JSONConfig(String path)
    {
        this.Path = path;
        pathfile = new File(path);
        if (pathfile.exists()){
            JsonParser jp = new JsonParser();
            try {
                Type typeOfHashMap = new TypeToken<Map<String,Object>>() { }.getType();
                this.config = new Gson().fromJson(FileUtils.readFileToString(new File(path)), typeOfHashMap);
            } catch (IOException e) {
                Core.jp.getServer().getConsoleSender().sendMessage(ChatColor.RED+"[InformativeItems]: Whoops, our JSONConfigReader could not read the config: "+path);
                e.printStackTrace();
            }
        } else {
            this.config = new HashMap<String,Object>();
            try {
                FileUtils.writeStringToFile(pathfile, config.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Core.jp.getServer().getConsoleSender().sendMessage(ChatColor.GREEN+"[InformativeItems]: Config Loaded ("+path+")");
    }



    public Map<String,Object> getConfig(){return this.config;}

    public void reload(){
        JsonParser jp = new JsonParser();
        try {
            Type typeOfHashMap = new TypeToken<Map<String,Object>>() { }.getType();
            this.config = new Gson().fromJson(FileUtils.readFileToString(new File(this.Path)), typeOfHashMap);
        } catch (IOException e) {
            Core.jp.getServer().getConsoleSender().sendMessage(ChatColor.RED+"[InformativeItems]: Whoops, our JSONConfigReader could not read the config: "+Path);
            e.printStackTrace();
        }
    }

    public void save(){
        try {
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            FileUtils.writeStringToFile(pathfile, gson.toJson(gson.toJsonTree(config)));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

在核心中,我有一条语句读取配置并循环遍历其值。

从配置中序列化的所有值仅包含一种类型的 class 作为值:InformativeItemProvider。

正如您在 JSONConfig 中看到的那样,所有 keys/values 都存储在 Map 中,键在对象 class 中,因此它们可以转换为任何内容。

因此,由于我知道在这种情况下(在核心中)所有值都是 InformativeItemProvider,所以我确实让所有值都转换为 InformativeItemProvider。这就是它出错的地方。
json 已成功从字符串转换为映射。 但是当我尝试将对象从地图投射到 InformativeItemProvider(它实际上是什么)时,它给了我错误。

提前致谢!

当您创建以下内容时 TypeToken:

Type typeOfHashMap = new TypeToken<Map<String,Object>>() { }.getType();

您无需告诉 Gson 任何有关您希望它创建的对象类型的信息。因此,它将简单地创建代表 JSON 个子结构的最模糊的对象:LinkedTreeMaps。这就是为什么如果您尝试将这些对象转换为其他对象,您会得到 ClassCastException

您的问题的第一个解决方案是改用 Map<String,InformativeItemProvider>。并提供一个 TypeToken,它实际上提供了有关您想要的具体类型的信息:

Type typeOfHashMap = new TypeToken<Map<String,InformativeItemProvider>>() { }.getType();

然后,如果你想重用你的 class,你可以先将 json 解析从文件 I/O 中分离出来,你会发现几乎没有什么可以重用的Gson 部分。