Gson LinkedTree映射无法转换为InformativeItemProvider

时间:2017-03-28 20:56:34

标签: java gson bukkit

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

我的插件在这种情况下,Minecraft存在于3个重要类中,但只有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();
        }
    }

}

在核心中,我有一个声明,通过其值读取配置和循环。

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

正如您在JSONConfig中看到的,所有键/值都存储在Map中,键位于Object类中,因此可以将它们转换为任何类型。

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

提前致谢!

1 个答案:

答案 0 :(得分:3)

创建以下TypeToken时:

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

您不会告诉Gson您希望它创建的对象类型。因此,它只会创建代表JSON子结构的最模糊的对象:LinkedTreeMap s。如果您尝试将这些对象转换为其他对象,那么这就是ClassCastException的原因。

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

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

然后,如果你想重新使用你的类,你可以先将json解析与文件I / O分开,你会发现几乎没有关于Gson部分的重用。