Java 泛型 - Stackoverflow
Java Generics - Stackoverflow
我在使用以下泛型时遇到 WhosebugError:
积分:
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.WhosebugError
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 都是 class 用于 serialize/deserialize 的。例如,当在 JSONSpawn 中调用 load() 时,它会将 MemoryPoints 中的 spawn 值设置为从 json 文件序列化的对象。那是为了 JSONSpawn class。当在 JSONRandomPoints 中调用 load() 时,它再次在 MemoryPoints 中设置一个值(class 用于处理变量的 setter 和 getter),但这次是针对点。使用了 JSONPoints,因此我可以同时在 JSONSpawn 和 JSONRandomPoints 中调用 load()。
因此 Points.getInstance().loadAll() 将通过调用 JSONSpawn 和 JSONRandomPoints 中的 load() 来设置 MemoryPoints 中的两个变量。保存也是如此(这与加载是一样的)。
例如程序加载:
Points.getInstance().loadAll().
现在 MemoryPoints 中的变量(spawn 和点)已经通过在 classes JSONSpawn 和 JSONRandomPoints 中调用 load() 来设置。但我仍然可以使用:
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 构造函数,它...
因此出现 WhosebugError。
阅读堆栈跟踪可以清楚地了解这一点。你清楚地看到两个构造函数的递归调用:
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) ~[?:?]
我无法真正提出修复建议,因为我不知道所有这些 类 的用途。我只能说,其中大多数 类 可能不应该相互延伸。
我在使用以下泛型时遇到 WhosebugError:
积分:
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.WhosebugError
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 都是 class 用于 serialize/deserialize 的。例如,当在 JSONSpawn 中调用 load() 时,它会将 MemoryPoints 中的 spawn 值设置为从 json 文件序列化的对象。那是为了 JSONSpawn class。当在 JSONRandomPoints 中调用 load() 时,它再次在 MemoryPoints 中设置一个值(class 用于处理变量的 setter 和 getter),但这次是针对点。使用了 JSONPoints,因此我可以同时在 JSONSpawn 和 JSONRandomPoints 中调用 load()。
因此 Points.getInstance().loadAll() 将通过调用 JSONSpawn 和 JSONRandomPoints 中的 load() 来设置 MemoryPoints 中的两个变量。保存也是如此(这与加载是一样的)。
例如程序加载:
Points.getInstance().loadAll().
现在 MemoryPoints 中的变量(spawn 和点)已经通过在 classes JSONSpawn 和 JSONRandomPoints 中调用 load() 来设置。但我仍然可以使用:
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 构造函数,它...
因此出现 WhosebugError。
阅读堆栈跟踪可以清楚地了解这一点。你清楚地看到两个构造函数的递归调用:
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) ~[?:?]
我无法真正提出修复建议,因为我不知道所有这些 类 的用途。我只能说,其中大多数 类 可能不应该相互延伸。