当前位置: 首页 > 知识库问答 >
问题:

使用Gson反序列化通过接口引用可访问的泛型类实例

林弘文
2023-03-14

我正在使用Universal Java Matrix包,它的工作非常好,但是我不能让它在Gson中发挥出色--序列化似乎工作得很好,但这是更容易的部分,当然。
反序列化会产生一些问题,因为我正在尝试将JSON反序列化到一个类的实例中,这个类具有类型为DefaultDenseGenericMatrix2D的泛型私有成员,其中Square是我自己的类。DefaultDenseGenericMatrix2D实现了我用来引用实际成员的矩阵接口。因此,接口本身不是泛型的,但实现它的类实际上是泛型的。我尝试使用了RuntimeTypeAdapterFactory,它不包含在Gson库中,但可以在它们的GitHub存储库中找到。

我在Android上用这个,如果有关系的话。

这是它目前的样子:

// Grid
public class Grid implements Cloneable {
    private GridPosition _position; // works fine
    private GridSize _size; // this one also
    private int _dimensions; // like this one, as well
    private Matrix _squaresMatrix; // this little rascal refuses to play nice

    public Grid(GridPosition position, GridSize size) {
        _position = position;
        _size = size;

        Integer sizeValue = Converters.valueOf(size);
        _dimensions = sizeValue != null ? sizeValue : 0;

        // as you can see, it really is generic but the interface isn't
        _squaresMatrix = new DefaultDenseGenericMatrix2D<Square>(_dimensions, _dimensions); // can be either 10, 15 or 20 (100, 225 or 400 elements in total)

        // initializing the matrix, doesn't really matter
        for (long[] coordinates : _squaresMatrix.allCoordinates()) {
            Long x = coordinates[0];
            Long y = coordinates[1];

            _squaresMatrix.setAsObject(new Square(SquareState.VACANT, new Coordinates(x.intValue(), y.intValue())), coordinates);
        }
    }

    // ... (unimportant stuff)
}

/*********************************************/

// Square
public class Square {
    // all members are otherwise serialized correctly, on their own
    private SquareState _state;
    private Coordinates _coordinates;
    private Ship _owner;

    public Square(SquareState state, Coordinates coordinates) {
        _state = state;
        _coordinates = coordinates;
        _owner = null;
    }

    // ... (unimportant stuff)
}

/*********************************************/

// constructing the Gson object
Type genericType = new TypeToken<DefaultDenseGenericMatrix2D<Square>>(){}.getType(); // not used (where to put it?)
final RuntimeTypeAdapterFactory<Matrix> typeFactory = RuntimeTypeAdapterFactory
        .of(Matrix.class, "_squaresMatrix")
        // DefaultDenseGenericMatrix2D<Square>.class is illegal, of course (wouldn't make sense either way due to the infamous type erasure)
        .registerSubtype(DefaultDenseGenericMatrix2D.class);

GsonBuilder builder = new GsonBuilder().registerTypeAdapterFactory(typeFactory);
Gson gson = builder.create();

在反序列化过程中,“_squaresMatrix”字段确实被反序列化了,但我得到的不是Square类型的DefaultDenseGenericMatrix2D,而是LinkedTreeMap类型的一个,因为Gson不知道实际使用哪种类型,而且DefaultDenseGenericMatrix2D类本身当然可以与普通的旧对象一起工作。
我相信解决方案可能是在某个地方使用TypeToken类,但我不知道将它合并到哪里。
作为最后的手段,我可以将LinkedTreeMap实例映射到Square类型的实例,因为数据在那里,但如果可能,我希望尽量避免这样做。

提前谢谢你。

共有1个答案

慕容恩
2023-03-14

使用InstanceCreator允许您告诉Gson如何创建特定类型的实例。

在这里,您可以告诉它每次找到矩阵时创建DefaultDenseGenericMatrix2D :

GsonBuilder builder = new GsonBuilder().registerTypeAdapter(Matrix.class, new MatrixInstanceCreator());
Gson gson = builder.create();

MatrixInStanceCreator为:

public class MatrixInstanceCreator()  implements InstanceCreator<Matrix> {
    @Override
    public Matrix createInstance() {
        // the dimensions will be overridden by Gson anyway
        return new DefaultDenseGenericMatrix2D<Square>(0, 0);
    }
}
 类似资料:
  • 我在Android应用程序中实现Json反序列化时遇到了一些问题(带有Gson库)

  • 问题内容: 我正在使用GSON 1.4,并使用两个通用对象序列化对象,如下所示 。当我对它进行反序列化时 可悲的是我得到了 java.lang.IllegalArgumentException:无法将java.util.ArrayList字段…设置为java.util.LinkedList 这是为什么 ?GSON文档指出,如果我使用object.class参数进行序列化,则它支持泛型。任何想法?谢

  • 问题内容: 我在Android应用程序(带有Gson库)中实现Json反序列化存在一些问题 我已经上了这样的课 反序列化的调用是: 问题是调用后的result.posts列表包含一个LinkedTreeMap对象数组(具有正确的值,因此问题是反序列化)而不是MyJson对象。当我使用MyObject而不是T时,一切运行正常并且MyObject是正确的。 那么,有什么方法可以在不创建自定义反序列化器

  • 我有一个Api,Api如下所示: 如果响应是ok,那么结构将以关键字开头,例如: 问题是:我如何为父类创建一个反序列化器,它也会反序列化子类(作为我的第二种方法),或者我如何用Gson创建一个泛型类,这样包装在周围的每个tyoe都可以与它一起使用,比如: public class DataObjectDeserializer implements JsonDeserializer{

  • 您将获得对象(或对象列表),而不是作为传递的实际对象(或第二种情况下的实际对象列表)。 如果您想要一个仍然想要反序列化泛型类型对象(-s),请参阅下面的答案。 +红利:LoopJ+GSON的最终通用解决方案 如何获取泛型接口的具体类型 Java类型Generic作为GSON的参数