使用gson fromjson来解析子类

时间:2014-05-20 00:22:26

标签: java json inheritance gson

我正在使用Gson将json字符串解析为Vector,它存储了1-2个不同的BackgroundShape子类。
例如,BGRectangleBGTriangle 当我尝试解析字符串时,我收到此错误..

FileReader in = new FileReader("levels/level1.json");
BufferedReader br = new BufferedReader(in);
LevelDefinition ld = new Gson().fromJson(br, LevelDefinition.class);

Caused by: java.lang.StackOverflowError
    at com.google.gson.internal.$Gson$Types.resolve

有没有更好的方法来实现这一点?
我正在尝试将子类放入其父类型的Vector中。 这是父类......

public abstract class Shape{

    protected int textureIndex;

    /**
     * @param textureIndex
     */
    public Shape(int textureIndex) {
        this.textureIndex = textureIndex;
    }

    protected abstract void draw(GLAutoDrawable gLDrawable);
}

BackgroundShape子类Shape ..

public abstract class BackgroundShape extends Shape{

    private Vec3 position;

    public BackgroundShape(Vec3 position, int textureIndex) {
        super(textureIndex);

        this.position = position;
    }
}

BGRectangle延伸BackgroundShape ..

public class BGRectangle extends BackgroundShape{

    private float width;
    private float height;

    public BGRectangle (Vec3 position int textureIndex, float width, float height) { 
        super(position, textureIndex);

        this.width = width;
        this.height = height;
    };

    @Override
    public void draw(GLAutoDrawable gLDrawable) {
    }
}

这是我在json中声明的方式(演示只有1 BackgroundShape)..

{
    "bgShapes": [
        {
            "position": {
                "x": 0.0,
                "y": 50.0,
                "z": -20.0
            },
                    "textureSelection": 1,
            "width": 450.0,
            "height": 200.0
        }
    ]
}

我的Java类代表这个json字符串..

public class LevelDefinition {

    private Vector<BackgroundShape> bgShapes;

    /**
     * @return the bgShapes
     */
    public Vector<BackgroundShape> getBgShapes() {
        return bgShapes;
    }
    /**
     * @param bgShapes the bgShapes to set
     */
    public void setBgShapes(Vector<BackgroundShape> bgShapes) {
        this.bgShapes = bgShapes;
    }
}

1 个答案:

答案 0 :(得分:0)

对我来说看起来像this bug

我解决这个问题的方法是编写自己的JsonReaderJsonWriter。您可以在我的答案中详细了解如何执行此操作:How do I implement TypeAdapterFactory in Gson?

基本上,在read中实现TypeAdapter方法来创建所需的Vector类。如果这还不足以让你弄清楚,请告诉我,我会尝试添加更多细节。

你可以从这样的事情开始:

public enum ShapeTypeAdapterFactory implements TypeAdapterFactory {
    INSTANCE;

    private static class ShapeTypeAdapter extends TypeAdapter<BackgroundShape> {
        @Override
        public final void write(JsonWriter out, BackgroundShape value) throws IOException {
            if(value == null) {
                out.nullValue();
                return;
            }

            // Your code goes here
        }

        @Override
        public final BackgroundShape read(JsonReader in) throws IOException {
            if(in.peek() == JsonToken.NULL) {
                in.nextNull();
                return null;
            }

            // Your code goes here      

            // Don't return null, return the new object
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        if(!BackgroundShape.class.isAssignableFrom(type.getRawType())) {
            return null;
        }

        return (TypeAdapter<T>) new ShapeTypeAdapter();
    }
}

然后注册:

gsonBuilder.registerTypeAdapterFactory(ShapeTypeAdapterFactory.INSTANCE);

另外,请阅读此Javadoc以获取有关如何编写此示例中缺少的代码的更完整示例