【问题标题】:google Gson causing a stackoverflow谷歌 Gson 导致堆栈溢出
【发布时间】:2014-07-14 08:52:20
【问题描述】:
Error    
 07-14 04:33:28.030: E/AndroidRuntime(5216): FATAL EXCEPTION: main
    07-14 04:33:28.030: E/AndroidRuntime(5216): Process: com.tt, PID: 5216
    07-14 04:33:28.030: E/AndroidRuntime(5216): java.lang.StackOverflowError
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.String._getChars(String.java:908)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:147)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:216)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:154)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.ja

我的模范球员

package com.tt.models;
import java.util.Collection;
import com.google.gson.annotations.SerializedName;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "Player")
public class Player {
    public static final String BATTING_ID_FIELD_NAME = "batting_id";
    public static final String BOWLING_ID_FIELD_NAME = "bowling_id";
    public static final String TEAM_ID_FIELD_NAME = "team_id";
    @SerializedName("__v")
    @DatabaseField(id = true) 
     private int id;

    @SerializedName("_id")
    @DatabaseField(columnName = "_id")
    private String _id;
    /*@SerializedName("__v")
    @DatabaseField(columnName = "__v",id=true)
    private int __v;*/
    @DatabaseField
    private String battingStyle;
    @DatabaseField
    private String bowlingStyle;
    @DatabaseField
    private String dob;
    @DatabaseField
    private String playingRole;
    @DatabaseField
    private String sname;
    @DatabaseField
    private String fname;
    @SerializedName("gallery")
    @ForeignCollectionField(eager = true, maxEagerLevel = 2)
    private Collection<Gallery> gallery;

    @SerializedName("games")
    @ForeignCollectionField(eager = true)
    private Collection<Game> games;

    /*
     * @DatabaseField(dataType = DataType.SERIALIZABLE) private String[] users;
     */
    /*
     * @DatabaseField(dataType = DataType.SERIALIZABLE) private String[] squad;
     */

    Player() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }


    public String getBattingStyle() {
        return battingStyle;
    }

    public void setBattingStyle(String battingStyle) {
        this.battingStyle = battingStyle;
    }

    public String getBowlingStyle() {
        return bowlingStyle;
    }

    public void setBowlingStyle(String bowlingStyle) {
        this.bowlingStyle = bowlingStyle;
    }

    public String getDob() {
        return dob;
    }

    public void setDob(String dob) {
        this.dob = dob;
    }

    public String getPlayingRole() {
        return playingRole;
    }

    public void setPlayingRole(String playingRole) {
        this.playingRole = playingRole;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    /*
     * public String[] getUsers() { return users; }
     * 
     * public void setUsers(String[] users) { this.users = users; }
     */

    /*
     * public String[] getSquad() { return squad; }
     * 
     * public void setSquad(String[] squad) { this.squad = squad; }
     */

    public Collection<Gallery> getGallerys() {
        return gallery;
    }

    public void setGallerys(Collection<Gallery> gallery) {
        this.gallery = gallery;
    }

    public Collection<Gallery> getGallery() {
        return gallery;
    }

    public void setGallery(Collection<Gallery> gallery) {
        this.gallery = gallery;
    }

    public Collection<Game> getGames() {
        return games;
    }

    public void setGames(Collection<Game> games) {
        this.games = games;
    }

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }

    @Override
    public String toString() {
        return "Player [id=" + Integer.toString(id) + ", _id=" + _id + ", battingStyle="
                + battingStyle + ", bowlingStyle=" + bowlingStyle + ", dob="
                + dob + ", playingRole=" + playingRole + ", sname=" + sname
                + ", fname=" + fname + ", gallery=" + gallery + ", games="
                + games + "]";
    }






}
and game model 
package com.tt.models;

import java.util.Collection;

import com.google.gson.annotations.SerializedName;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "Game")
public class Game {
    public static final String INNING_ID_FIELD_NAME = "inning_id";
    public static final String PLAYER_ID_FIELD_NAME = "player_id";
    @SerializedName("__v")
    @DatabaseField(id = true) 
     private int id;

    /*@SerializedName("_id")
    @DatabaseField(columnName = "_id")
    private String _id;
    @SerializedName("__v")
    @DatabaseField(columnName = "__v",id=true)
    private int __v;*/
    @SerializedName("gameType")
    @DatabaseField
    private String gameType;
    @SerializedName("name")
    @DatabaseField
    private String name;
    @SerializedName("totalOvers")
    @DatabaseField
    private String totalOvers;
    @SerializedName("dateStarted")
    @DatabaseField
    private String dateStarted;
    @SerializedName("dateEnded")
    @DatabaseField
    private String dateEnded;
    @SerializedName("innings")
    @ForeignCollectionField(eager = true, maxEagerLevel = 2)
    private Collection<Inning> innings;
    @DatabaseField(foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true, columnName = PLAYER_ID_FIELD_NAME)
    private Player player;
    @SerializedName("grounds")
    @ForeignCollectionField(eager = true, maxEagerLevel = 2)
    private Collection<Ground> grounds;
    @SerializedName("teams")
    @ForeignCollectionField(eager = true, maxEagerLevel = 2)
    private Collection<Team> teams;

    public Game() {
        // all persisted classes must define a no-arg constructor with at least
        // package visibility
    }



    /*public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }*/

    public String getGameType() {
        return gameType;
    }

    public int getId() {
        return id;
    }



    public void setId(int id) {
        this.id = id;
    }



    public void setGameType(String gameType) {
        this.gameType = gameType;
    }

    public Collection<Ground> getGrounds() {
        return grounds;
    }

    public void setGrounds(Collection<Ground> grounds) {
        this.grounds = grounds;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDateStarted() {
        return dateStarted;
    }

    public void setDateStarted(String dateStarted) {
        this.dateStarted = dateStarted;
    }

    public String getDateEnded() {
        return dateEnded;
    }

    public void setDateEnded(String dateEnded) {
        this.dateEnded = dateEnded;
    }

    public String getTotalOvers() {
        return totalOvers;
    }

    public void setTotalOvers(String totalOvers) {
        this.totalOvers = totalOvers;
    }

    public Player getPlayer() {
        return player;
    }

    public void setPlayer(Player player) {
        this.player = player;
    }

    public Collection<Inning> getInnings() {
        return innings;
    }

    public void setInnings(Collection<Inning> innings) {
        this.innings = innings;
    }

    public Collection<Team> getTeams() {
        return teams;
    }

    public void setTeams(Collection<Team> teams) {
        this.teams = teams;
    }



    @Override
    public String toString() {
        return "Game [id=" + Integer.toString(id) + ", gameType=" + gameType + ", name=" + name
                + ", totalOvers=" + totalOvers + ", dateStarted=" + dateStarted
                + ", dateEnded=" + dateEnded + ", innings=" + innings
                + ", player=" + player + ", grounds=" + grounds + ", teams="
                + teams + "]";
    }

    /*public int get__v() {
        return __v;
    }

    public void set__v(int __v) {
        this.__v = __v;
    }*/

【问题讨论】:

    标签: android json gson


    【解决方案1】:

    Player 有Game,Game 有Player,Player 有Game,Game 有Player...stackoverflow。

    改变你的类的结构。消除循环引用,或在Player 或Game 引用上使用transient 关键字将其从序列化中排除。

    编辑:

    如果您不想更改类的结构,例如:每个 Game 都引用了 Player,但 Player 没有引用他的 Games。然后你可以这样做:

    • 序列化播放器
    • 玩家将序列化其游戏收藏
    • Game 类应该有privatetransientPlayer player; 字段, 避免StackOverflowError
    • 反序列化后,播放器应迭代其游戏并 给他们每个人打电话game.setPlayer(this);

    您还需要修复您的 toString() 方法。因为Player 类的toString() 方法调用Game 类的toString(),它调用Player 类的toString()。

    当您收到StackOverflowError 时,只需查找类似的内容。或者不要构建这样的类结构,每个Player 都有他的Games,每个Game 都有它的Player。

    【讨论】:

    • 嗨 mike_m 它的关系定义一个玩家有很多游戏,很多游戏有一个玩家,所以如果我使用瞬态关键字,那么它如何使用..
    • @DatabaseField(foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true, columnName = PLAYER_ID_FIELD_NAME) 私有临时玩家播放器;游戏类中的玩家和玩家类中的游戏 @SerializedName("games") @ForeignCollectionField(eager = true) private Collection games;和我的控制器 Iterator iteratorGame = player.getGames().iterator(); while (iteratorGame.hasNext()) { 游戏游戏 = (Game) iteratorGame.next(); if (game != null) { game.setPlayer(player);
    • @ShoaibAhmad 你改变了一些东西并得到了其他类型的错误?如果您修复了StackOverflowError,那么您可能需要将其作为新问题发布。如果您仍然得到StackOverflowError,那么您需要查找 Player 调用 Game、Game 调用 Player 等的地方。或者,也许您对 Team 课程也有问题?我没有看到那个类,但也许它也有对 Player/Game 的引用,并且它们以无限递归的方式相互调用。
    • @Override public String toString() { return "Player [id=" + id + ", _id=" + _id + ", battingStyle=" + battingStyle + ", bowlingStyle=" + bowlingStyle + ", dob=" + dob + ", playingRole=" + playingRole + ", sname=" + sname + ", fname=" + fname + ", gallery=" + gallery +", games=" + games + "] "; }
    • @Override public String toString() { return "Game [id=" + id + ", gameType=" + gameType + ", name=" + name + ", totalOvers=" + totalOvers + ", dateStarted=" + dateStarted + ", dateEnded=" + dateEnded + ", innings=" + innings + ", grounds=" + grounds + ", teams=" + teams + "]"; }
    猜你喜欢
    • 2015-05-21
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    相关资源
    最近更新 更多