我通过使用以下泛型得到了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) ~[?:?]


我真的不能提出修复建议,因为我不知道所有这些类的用途。我只能说大多数此类都不应该相互扩展。

10-07 21:46