gpt4 book ai didi

java - 使用 Gson 反序列化可通过接口(interface)引用访问的通用类实例

转载 作者:行者123 更新时间:2023-12-01 09:29:35 27 4
gpt4 key购买 nike

我正在使用Universal Java Matrix Package它工作得非常好,但我无法让它与 Gson 很好地配合 - 序列化似乎工作得很好,但当然这是更容易的部分。
反序列化会产生一些问题,因为我试图将 JSON 反序列化为一个类的实例,该类具有 DefaultDenseGenericMatrix2D 类型的通用私有(private)成员,其中 Square 是我自己的类。 DefaultDenseGenericMatrix2D其中,实现 Matrix我用来引用实际成员的接口(interface)。因此,接口(interface)本身不是通用的,但实际上实现它的类是通用的。我尝试过使用 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 类型的实例,因为数据就在那里,但如果可能的话,我想尽量避免这种情况。

提前谢谢您。

最佳答案

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

在这里你可以告诉它创建一个 DefaultDenseGenericMatrix2D<Square>每次它找到 Matrix :

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);
}
}

警告:尽管如此,这并不是很强大,因为每个Matrix在您的应用程序中将创建为 DefaultDenseGenericMatrix2D<Square> 。但是,如果您只有这个,或者您的所有Matrix属于具体类型,无论如何这都会满足您的需求。

关于java - 使用 Gson 反序列化可通过接口(interface)引用访问的通用类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39556500/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com