我通过使用以下泛型得到了StackOverflowError:
要点:
package me.expdev.gkitpvp;
/*
* Project created by ExpDev
*/
import me.expdev.gkitpvp.persist.json.JSONPoints;
public abstract class Points {
private static Points instance = getPointsImpl();
public static Points getInstance() {
return instance;
}
private static Points getPointsImpl() {
return new JSONPoints();
}
public abstract GLocation getSpawn();
public abstract void setSpawn(GLocation loc);
public abstract GLocation getPoint(String id);
public abstract void addPoint(String id, GLocation loc);
public abstract void removePoint(String id);
// LOAD
public abstract void loadAll();
// SAVE
public abstract void forceSaveAll();
}
MemoryPoints扩展点:
package me.expdev.gkitpvp.persist;
import me.expdev.gkitpvp.GLocation;
import me.expdev.gkitpvp.Points;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
/**
* Project created by ExpDev
*/
public abstract class MemoryPoints extends Points {
public GLocation spawn = null;
public Map<String, GLocation> points = new ConcurrentSkipListMap<String, GLocation>(String.CASE_INSENSITIVE_ORDER);
public GLocation getSpawn() {
return spawn;
}
public void setSpawn(GLocation spawn) {
this.spawn = spawn;
}
public GLocation getPoint(String id) {
return points.get(id);
}
public void addPoint(String id, GLocation where) {
points.put(id, where);
}
public void removePoint(String id) {
points.remove(id);
}
// LOAD
@Override
public abstract void loadAll();
// SAVE
@Override
public abstract void forceSaveAll();
}
JSONPoints扩展MemoryPoints:
package me.expdev.gkitpvp.persist.json;
import me.expdev.gkitpvp.persist.MemoryPoints;
/*
* Project created by ExpDev
*/
public class JSONPoints extends MemoryPoints {
private JSONSpawn jsonSpawn;
private JSONRandomPoints jsonRandomPoints;
public JSONPoints() {
this.jsonSpawn = new JSONSpawn();
this.jsonRandomPoints = new JSONRandomPoints();
}
// LOADING
@Override
public void loadAll() {
jsonSpawn.load();
jsonRandomPoints.load();
}
// SAVING
@Override
public void forceSaveAll() {
jsonSpawn.forceSave();
jsonRandomPoints.forceSave();
}
}
JSONSpawn扩展JSONPoints:
https://pastebin.com/sgswhBEH
package me.expdev.gkitpvp.persist.json;
import com.google.gson.Gson;
import me.expdev.gkitpvp.GKitPvPPlugin;
import me.expdev.gkitpvp.GLocation;
import me.expdev.gkitpvp.utils.DiscUtil;
import java.io.File;
/**
* Project created by ExpDev
*/
public class JSONSpawn extends JSONPoints {
// Info on how to persist
private Gson gson;
private File file;
public JSONSpawn() {
file = new File(GKitPvPPlugin.p.getDataFolder(), "spawn.json");
gson = GKitPvPPlugin.gson;
}
public Gson getGson() {
return gson;
}
public void setGson(Gson gson) {
this.gson = gson;
}
public void forceSave() {
forceSave(true);
}
public void forceSave(boolean sync) {
saveCore(file, this.spawn, sync);
}
private boolean saveCore(File target, GLocation data, boolean sync) {
return DiscUtil.writeCatch(target, this.gson.toJson(data), sync);
}
public void load() {
GLocation spawn = this.loadCore();
if (spawn == null) {
return;
}
this.spawn = spawn;
GKitPvPPlugin.p.log("Loaded spawn.");
}
private GLocation loadCore() {
if (!this.file.exists()) {
return null;
}
String content = DiscUtil.readCatch(this.file);
if (content == null) {
return null;
}
GLocation data = this.gson.fromJson(content, GLocation.class);
saveCore(this.file, data, true); // Update the flatfile
return data;
}
}
JSONRandomPoints扩展JSONPoints:
https://pastebin.com/C7bEvkxc
package me.expdev.gkitpvp.persist.json;
/*
* Project created by ExpDev
*/
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import me.expdev.gkitpvp.GKitPvPPlugin;
import me.expdev.gkitpvp.GLocation;
import me.expdev.gkitpvp.utils.DiscUtil;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class JSONRandomPoints extends JSONPoints {
// Info on how to persist
private Gson gson;
private File file;
public JSONRandomPoints() {
file = new File(GKitPvPPlugin.p.getDataFolder(), "points.json");
gson = GKitPvPPlugin.gson;
}
public Gson getGson() {
return gson;
}
public void setGson(Gson gson) {
this.gson = gson;
}
public void forceSave() {
forceSave(true);
}
public void forceSave(boolean sync) {
saveCore(file, this.points, sync);
}
private boolean saveCore(File target, Map<String, GLocation> data, boolean sync) {
return DiscUtil.writeCatch(target, this.gson.toJson(data), sync);
}
public void load() {
Map<String, GLocation> points = this.loadCore();
if (points == null) {
return;
}
this.points.clear();
this.points.putAll(points);
GKitPvPPlugin.p.log("Loaded " + points.size() + " points");
}
private Map<String, GLocation> loadCore() {
if (!this.file.exists()) {
return new HashMap<String, GLocation>();
}
String content = DiscUtil.readCatch(this.file);
if (content == null) {
return null;
}
Map<String, GLocation> data = this.gson.fromJson(
content,
new TypeToken<Map<String, GLocation>>() {
}.getType());
saveCore(this.file, data, true); // Update the flatfile
return data;
}
}
堆栈跟踪:
java.lang.StackOverflowError
at me.expdev.gkitpvp.Points.<init>(Points.java:9) ~[?:?]
at me.expdev.gkitpvp.persist.MemoryPoints.<init>(MemoryPoints.java:14) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONPoints.<init>(JSONPoints.java:14) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONSpawn.<init>(JSONSpawn.java:22) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONPoints.<init>(JSONPoints.java:15) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONSpawn.<init>(JSONSpawn.java:22) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONPoints.<init>(JSONPoints.java:15) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONSpawn.<init>(JSONSpawn.java:22) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONPoints.<init>(JSONPoints.java:15) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONSpawn.<init>(JSONSpawn.java:22) ~
所以它继续。
--
这是泛型的问题,但我不能完全确定。有什么办法吗?
编辑:
我正在尝试做的事情:JSONSpawn和JSONRandomPoints都是用于序列化/反序列化的类。例如,当在JSONSpawn中调用load()时,它将把MemoryPoints中的spawn值设置为从json文件序列化的对象。那是针对JSONSpawn类的。当在JSONRandomPoints中调用load()时,它将再次在MemoryPoints中设置一个值(用于处理变量的setter和getter的类),但这一次是为点。使用JSONPoints,因此我可以同时在JSONSpawn和JSONRandomPoints中调用load()。
因此,Points.getInstance()。loadAll()将通过调用JSONSpawn和JSONRandomPoints中的load()来设置MemoryPoints中的两个变量。保存也一样(与加载相同)。
例如在程序加载时:
Points.getInstance().loadAll().
现在,可以通过在JSONSpawn和JSONRandomPoints类中调用load()来设置MemoryPoints中的变量(生成和点)。但我仍然可以使用:
Points.getInstance().getSpawn(); // returns spawn in MemoryPoints
最佳答案
您似乎在滥用继承。无论如何,在JSONPoints中,
public JSONPoints() {
this.jsonSpawn = new JSONSpawn();
this.jsonRandomPoints = new JSONRandomPoints();
}
因此,每次创建JSONPoints实例时,都会创建JSONSpawn实例和JSONRandomPoints实例。
但是这两个类都扩展了JSONPoints。
因此,创建JSONPoints会调用JSONSpawn构造函数,该构造函数将(隐式地)调用其超类构造函数,并调用JSONSpawn构造函数,其将(间接地)调用其超类构造函数,该构造函数将调用JSONSpawn构造函数,从而...
因此,StackOverflowError。
读取堆栈跟踪信息可以使BTW变得清晰。您清楚地看到两个构造函数的递归调用:
at me.expdev.gkitpvp.persist.json.JSONPoints.<init>(JSONPoints.java:14) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONSpawn.<init>(JSONSpawn.java:22) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONPoints.<init>(JSONPoints.java:15) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONSpawn.<init>(JSONSpawn.java:22) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONPoints.<init>(JSONPoints.java:15) ~[?:?]
at me.expdev.gkitpvp.persist.json.JSONSpawn.<init>(JSONSpawn.java:22) ~[?:?]
我真的不能提出修复建议,因为我不知道所有这些类的用途。我只能说大多数此类都不应该相互扩展。