简体   繁体   English

从GSON到Json的大量StackOverflowError

[英]Massive StackOverflowError from GSON toJson

So I am trying to use GSON to convert a class into a JSON file with the toJson() function and every time the code gets called there is a massive 1000+ line StackOverflowError. 因此,我尝试使用GSON通过toJson()函数将类转换为JSON文件,并且每次调用该代码时,都会出现大量的1000+行StackOverflowError。 This is the error: http://pastebin.com/dBhYUFva 这是错误: http : //pastebin.com/dBhYUFva

And here is the class I am doing gson.toJson() on: 这是我在做gson.toJson()的类:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import mc.kwit.arena.players.ArenaPlayer;
import mc.kwit.arena.util.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Zach on 8/3/16.
 */
public class Match {

    List<ArenaPlayer> arenaPlayers = new ArrayList<ArenaPlayer>();
    String[] uuidArray = null;
    Player winner;
    String matchId = "123456";
    int killLimit = 5;
    int timeLimit = -1;


    public Match() {

    }

    public Match(List<ArenaPlayer> arenaPlayerList, String id, int seconds, int kills) {
        this.arenaPlayers = arenaPlayerList;
        this.matchId = id;
        this.timeLimit = seconds;
        this.killLimit = kills;
    }

    public Match(String[] players, String id, int seconds, int kills) {
        this.uuidArray = players;
        this.matchId = id;
        this.timeLimit = seconds;
        this.killLimit = kills;
    }

    public void start() {

        //Create our ArenaPlayer objects
        this.arenaPlayers = PlayerUtil.uuidToArenaPlayerList(uuidArray);

        Bukkit.getLogger().info("Match \" " + this.matchId + "\" has been started!");
        //Whitelist all participants
        for(ArenaPlayer p : arenaPlayers) {
            KwitArena.pc.addArenaPlayer(p.getPlayer());
            p.getPlayer().setWhitelisted(true);
            Bukkit.getLogger().info(p.getName() + " has been whitelisted!");
            p.setMatch(this);
        }
    }

    public void finish() throws Exception {

        //Remove all players from whitelist and game
        for(ArenaPlayer p : arenaPlayers) {
            p.getPlayer().setWhitelisted(false);

            if(p.isWinner()){
                p.kick(ChatColor.GREEN + "You have won the game!");
                this.winner = p.getPlayer();
            } else {
                p.kick(ChatColor.RED + winner.getName() + "has won the game :(");
            }
        }

        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String stats = gson.toJson(this);
        KwitArena.postStats(stats);

        //Remove this arena instance from the plugin
        KwitArena.match = null;
    }

    public String getId(){
        return(this.matchId);
    }

    public void setWinner(ArenaPlayer p) {
        this.winner = p.getPlayer();
    }
}

ArenaPlayer.class : ArenaPlayer.class:

import mc.kwit.arena.Match;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;

/**
 * Created by Zach on 7/31/16.
 */
public class ArenaPlayer {

    ArenaPlayer ap;
    Player  player;
    OfflinePlayer offlinePlayer;
    int kills = 0;
    int deaths = 0;
    boolean isInGame = false;
    Match match = null;
    boolean isWinner = false;

    public ArenaPlayer(Player player){
        this.player = player;
    }

    public ArenaPlayer(Player player, boolean playing, int numKills, int numDeaths) {
        this.player = player;
        kills = numKills;
        deaths = numDeaths;
        isInGame = playing;
    }


    //Getters
    public String getMatchId() { return(this.match.getId());}

    public int getKills() { return(this.kills);}

    public int getDeaths() { return(this.deaths);}

    public Match getMatch() { return(this.match);}

    public Player getPlayer() { return(this.player);}

    public String getName() { return(player.getName());}

    public OfflinePlayer getOfflinePlayer() { return(this.offlinePlayer);}

    //Setters
    public void setMatch(Match match) { this.match = match;}

    public void setIsWinner(boolean b) { this.isWinner = b;}

    public void setOfflinePlayer(OfflinePlayer off) { this.offlinePlayer = off; }


    //Extras
    public void addDeath() { this.deaths++;}

    public void addKill() { this.kills++;}

    public boolean isPlaying() { return(this.isInGame);}

    public boolean isWinner() { return(this.isWinner);}

    public void kick(String message) { player.kickPlayer(message);}


}

I'm not really sure where to even begin in the stack trace, anyone have some pointers? 我真的不确定在堆栈跟踪中从哪里开始,有人有指针吗?

I think the problem is that Match has an ArenaPlayer field, and ArenaPlayer has a Match field, which if the two instances refetence each other causes Gson to go into an infinite loop due to its implementation. 我认为问题在于Match具有一个ArenaPlayer字段,而ArenaPlayer具有Match字段,如果这两个实例相互尊重,则Gson由于其实现而陷入无限循环。

You'll have to detangle your classes, your instances, or use a different library, or exclude certain fields from serialization - see Gson doc . 您将需要整理类,实例或使用其他库,或者从序列化中排除某些字段-请参阅Gson doc


BTW, 1000 is the default call stack depth - if you see this many lines in the stack, you've probably hit an infinite recursion. 顺便说一句,默认调用堆栈深度为1000-如果您在堆栈中看到这么多行,则可能遇到了无限递归。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM