首先:我知道这个错误很常见,而且看起来可能重复。
但事实并非如此,请阅读代码,然后我将解释我的错误。
在这种情况下,我的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(实际上是什么)时,它给了我错误。
提前致谢!
最佳答案
创建以下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部分几乎没有任何可重用的内容。