2017-05-07 51 views
0

我從使用下面的仿製藥獲得一個的StackOverflowError:Java泛型 - #1

點:

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,它再次將在MemoryPoints(用來處理該變量的getter和setter方法類)這個時間點的值,但是。使用JSONPoints,所以我可以同時在JSONSpawn和JSONRandomPoints中調用load()。

所以Points.getInstance()。LOADALL()將調用JSONSpawn和JSONRandomPoints負載()設置MemoryPoints兩個變量。保存也是一樣的(這與加載相同)。

上。例如程序加載:

Points.getInstance().loadAll(). 

現在MemoryPoints(產卵和分)變量已從調用類JSONSpawn和JSONRandomPoints負載()設定。但我仍然可以使用:

Points.getInstance().getSpawn(); // returns spawn in MemoryPoints 
+2

不,StackOverflowError與泛型沒有任何關係。您沒有發佈異常的堆棧跟蹤,這可以讓您知道發生異常的位置,而無需閱讀您發佈的代碼牆的每一行。 –

+0

@JB Nizet見編輯後。增加了堆棧跟蹤。 – ExpDev

+0

我認爲這種層次結構相當混亂。我的猜測是,當你實例化一個JSONRandom時,它調用構造函數,並且從其他點繼承而來,它們的構造函數也被調用。所以在某些情況下,一個類的構造函數會從另一個類調用構造函數,這會讓你的堆棧溢出。嘗試重新組織層次結構或向我們解釋您正在嘗試解決的問題。但是,這種泛型不會導致你的問題。 – Hellzzar

回答

4

你似乎在濫用繼承。不管怎樣,在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) ~[?:?] 

我真的不能提出一個解決方法,因爲我不知道什麼所有這些類的想法。我只能說大多數這些類可能不應該彼此延伸。

+0

我已經添加了一些代碼和解釋。 – ExpDev

+0

請你能提出一個解決方法嗎? @JB Nizet – ExpDev

+0

改變整個設計。除非有明確的is-a協會(香蕉是水果),否則不要使用繼承。對您的類給予明確的責任:要麼代表包含在JSON文檔中的數據,要麼用於操縱,保存,加載數據。我不能說比這更清楚,因爲你們班的名字和結構對我來說完全不清楚。他們有0個文件。 –