2016-04-26 12 views
0

Also habe ich Daten für eine Art von Freunden-System in einer MySQL-Datenbank gespeichert, und eine Art API, um die Daten in Java-Objekte abzurufen.Wie kann ich diesen rekursiven StackOverFlowException Fehler beheben?

Das Java-Objekt (MPlayer) enthält Dinge wie den Benutzernamen, Online-Status, Freunde (IDs getrennt durch ":"). Das MPlayer-Objekt übernimmt die eindeutige ID eines Spielers als Konstruktor.

Die Daten werden beim Erstellen und beim Aufruf der reload() -Methode im Objekt gespeichert. Dies ist, anstatt auf die Datenbank jedes Mal zuzugreifen, wenn ich etwas wie den Benutzernamen erhalten möchte. Der Grund dafür ist, dass ich die Daten in einer Schleife abrufen muss, um auf einer GUI angezeigt zu werden, und ich möchte natürlich nicht die Daten in jedem Frame herunterladen. Stattdessen verwende ich nur alle 6 Sekunden die Reload-Methode.

Eine der Funktionen ist getFriends() und gibt eine Liste von MPlayer zurück. Die Liste wird gespeichert, wenn das MPlayer-Objekt erstellt wird. Das Problem ist, wenn jede der MPlayer-Freunde erstellt wird, erstellt sie eine Liste für ihre Freunde, die wiederum eine Liste für ihre Freunde erstellt, die aufgrund einer Rekursion mit einer StackOverFlowException endet.

Was wäre eine gute Lösung, um den Fehler zu vermeiden?

-Code in Frage:

Der MPlayer Konstruktor/Load-Methode:

public MPlayer(String player){ 
    this.uuid = player; 
    try { 
     st.setString(1, uuid); 
    } catch (SQLException e) { 

     e.printStackTrace(); 
    } 
    this.reload(); 
} 

public void reload(){ 
    try { 
     ResultSet set = st.executeQuery(); 
     if(set.next()){ 
      if(set.getString("server").equals("none")){ 
       isConnected = false; 
      }else{ 
       isConnected = true; 
      } 
     } 
    } catch (SQLException e) { 

     e.printStackTrace(); 
    } 

    try { 
     ResultSet set = st.executeQuery(); 
     if(set.next()){ 
      this.serverIP = set.getString("server"); 
     } 
    } catch (SQLException e) { 

     e.printStackTrace(); 
    } 



    try { 

     ResultSet set = st.executeQuery(); 
     if(set.next()){ 
      this.username = set.getString("username"); 
     } 
    } catch (SQLException e) { 

     e.printStackTrace(); 
    } 


    try { 
     ResultSet get = st.executeQuery(); 
     if(get.next()){ 
      this.online = get.getBoolean("status"); 
     } 
    } catch (SQLException e) { 

     e.printStackTrace(); 
    } 
    try { 


     List<MPlayer> list = new ArrayList<MPlayer>(); 
     ResultSet get = st.executeQuery(); 
     if(get.next()){ 
      for(String str : get.getString("friends").split(":")){ 
       if(!str.equalsIgnoreCase("none")){ 
        MPlayer player = new MPlayer(str); 
        if(player.isOnline()){ 
         list.add(0,player); 
        }else{ 
         list.add(player); 
        } 
       } 
      } 

     } 
     this.friends = list; 
    } catch (SQLException e) { 

     e.printStackTrace(); 
    } 


    this.settings = new Settings(this); 


    PreparedStatement state = Main.getPreparedStatement("SELECT * FROM updates WHERE uuid=?"); 
    try { 
     state.setString(1, this.getUUID()); 
     ResultSet set2 = state.executeQuery(); 
     List<StatusUpdate> updates = new ArrayList<StatusUpdate>(); 

     while(set2.next()){ 
      updates.add(new StatusUpdate(set2.getInt(1))); 
     } 
      Collections.sort(updates, new Comparator<StatusUpdate>() { 
       @Override 
       public int compare(StatusUpdate r1, StatusUpdate r2) { 

        return -1 * r1.getDate().compareTo(r2.getDate()); 
       } 
      }); 

     this.updates = updates; 
    } catch (SQLException e) { 

     e.printStackTrace(); 
    } 


    List<StatusUpdate> updates = new ArrayList<StatusUpdate>(); 

    for(MPlayer p : this.getFriends()){ 
     updates.addAll(p.getStatusUpdates()); 

    } 
    updates.addAll(this.getStatusUpdates()); 
    Collections.sort(updates, new Comparator<StatusUpdate>() { 
     public int compare(StatusUpdate m1, StatusUpdate m2) { 

      return -1 * m1.getDate().compareTo(m2.getDate()); 
     } 
    }); 
    this.timeline = updates; 



} 
+1

Bitte poste deinen Code und den genauen Fehler, den du bekommst. [Fragen zu SO] (http://stackoverflow.com/help/how-to-ask). – Dresden

+0

Das Problem hier ist, dass Sie 'MPlayer player = new MPlayer (str)' aus der Funktion 'reload' aufrufen - aber im Konstruktor für' MPlayer' rufen Sie auch 'this.reload();' auf rufe 'MPlayer player = new MPlayer (str);' auf und so ist das Looping unendlich - ich denke, der erste Schritt sollte sein, deinen Code umzuformen - es ist keine gute Idee, dass deine 'reload' Funktion so viel macht ... – ishmaelMakitla

Antwort

0

Die offensichtliche Antwort ist "quit es rekursiv ohne Kündigung zu tun".

Sie wollen nicht unbegrenzte Schließung auf der Freundesliste - aber was tun Sie wollen? Nur die Liste der Freunde? In diesem Fall benötigen Sie möglicherweise einen separaten Objekttyp, z. B. "FriendList". Dazu listen Sie lediglich die Freundes-IDs auf; Laden Sie keinen Freundesdatensatz, bis auf ihn speziell zugegriffen wird.

Eine andere Möglichkeit besteht darin, die Anzahl der Ebenen zu programmieren, die Sie aktivieren möchten. Dies ist ein Parameter der Objektlast. Laden Sie Ihren primären MPlayer mit einer Tiefe von N = 2. Laden Sie für jeden Freund Ihres primären Benutzers eine Tiefe von N-1. Wenn Sie 0 drücken, listen Sie die ID auf, ohne den Datensatz zu laden (wie oben).

Macht Sie das in Richtung einer Lösung?

+0

Ich verstehe. Art eines schreibgeschützten Spielerobjekts? Danke, du bist einer der wenigen Fälle, in denen Leute nicht "du machst es total falsch, wiederhole deinen Code und komm später zurück". –

+0

Sie sind herzlich willkommen. Ja, schreibgeschützt ist eine Möglichkeit, es zu betrachten. Vor allem müssen Sie nur Ihre abgeleiteten Fälle von der primären trennen, um die unbegrenzte Rekursion zu brechen. – Prune

+0

Ich stimme den anderen zu, dass Ihr Code nicht "der natürliche Weg" ist, darüber nachzudenken, aber ich nehme an, dass Sie Ihren Problembereich besser kennen als wir. :-) Zum Beispiel unterstützt Ihr Ansatz möglicherweise Funktionen, die Sie noch nicht implementiert haben. – Prune

Verwandte Themen