2016-09-18 4 views
0

私はUniversal Java Matrix Packageを使用していますが、実際にはうまくいっていますが、Gsonでうまく再生できません - シリアル化はうまくいくようですが、 、 もちろん。
JSONを、DefaultDenseGenericMatrix2D型の汎用プライベートメンバーを持つクラスのインスタンスにデシリアライズしようとしているため、デシリアライゼーションに問題が発生しています。Squareは自分のクラスです。 DefaultDenseGenericMatrix2Dは、実際のメンバーを参照するために使用しているMatrixインターフェイスを実装しています。したがって、インタフェース自体は一般的ではありませんが、実際にはそれを実装するクラスがあります。 私はRuntimeTypeAdapterFactoryを使ってみましたが、それはGsonライブラリ自体には含まれていませんが、GitHubリポジトリにあります。Gsonを使用してインターフェイス参照からアクセス可能なジェネリッククラスインスタンスを非直列化する

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

Gsonは知らなかったので、「_squaresMatrix」フィールドが実際に非直列化ではなく、タイプ広場のDefaultDenseGenericMatrix2Dの私はタイプLinkedTreeMapの1を取得しています実際に使用するタイプで、DefaultDenseGenericMatrix2Dクラス自体は普通の古いオブジェクトでうまく動作します。
私は、ソリューションがどこかでTypeTokenクラスを使用している可能性があると考えていますが、私はそれを組み込むことはできません。
最後の手段として、LinkedTreeMapインスタンスをSquare型のインスタンスにマップすることができます。データが存在するためですが、可能であれば、それを回避しようとします。

ありがとうございます。

答えて

1

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

警告:これは、しかし、非常に堅牢ではありませんアプリケーション内のすべてのMatrixDefaultDenseGenericMatrix2D<Square>として作成されるためです。しかし、あなただけがこれを持っている場合、またはあなたのすべてのMatrixがその具体的なタイプのものであれば、これはあなたのニーズに合っています。

関連する問題