0

オブジェクトの大きな 2 次元配列をシリアライズおよびデシリアライズしています。各オブジェクトには、オブジェクトを作成するための指示が含まれています。これは、それ自体が直接シリアル化できないことをBufferedImage回避するために行われます。BufferedImage

シリアル化されるクラスは次のとおりです。

public final class MapTile extends TransientImage
{
    private static final long serialVersionUID = 0;
    private transient BufferedImage f;
    transient BufferedImage b;
    int along;
    int down;
    boolean flip = false;
    int rot = 0;

    public MapTile(World w, int a, int d)
    {
        // f = w.getMapTiles();
        along = a;
        down = d;
        assignImage();
    }

    public MapTile(World w, int a, int d, int r, boolean fl)
    {
        // f = w.getMapTiles();
        along = a;
        down = d;
        rot = r;
        flip = fl;
        assignImage();
    }

    public int getA()
    {
        return along;
    }

    public int getD()
    {
        return down;
    }

    @Override
    public void assignImage()
    {
        if (f == null)
        {
            f = World.mapTiles;
        }
        b = f.getSubimage(along, down, World.squareSize, World.squareSize);
        if (rot != 0)
        {
            b = SmallMap.rotateImage(b, rot);
        }
        if (flip)
        {
            b = SmallMap.flipImage(b);
        }
        super.setImage(b);
        f.flush();
        b.flush();
        f = null;
        b = null;
    }
}

拡張します:

public abstract class TransientImage implements Serializable
{
    private transient BufferedImage image;

    public BufferedImage getImage()
    {
        return image;
    }

    public void setImage(BufferedImage i)
    {
        image = i;
    }

    public abstract void assignImage();

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
    {
        in.defaultReadObject();
        assignImage();
    }
}

これは最終的にマップの一部になります。通常はランダムに作成されますが、特定の領域は毎回同じでなければならないため、それらをシリアル化し、配列を読み戻します。通常の使用中に画像を保存する必要がないため、入れています書き込みコード:

try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("verticalroad.necro"))) 
{
    //out.writeObject(mapArray);
    //}
    //catch (IOException e) {
//}

マップを作成するクラスで、読み取りコード:

    try{
        FileInputStream door = new FileInputStream(new File(f.getPath()+ "//verticalroad.necro"));
        ObjectInputStream reader = new ObjectInputStream(door);
        homeTiles = (MapTile[][]) reader.readObject();
        }
    catch (IOException | ClassNotFoundException e)
        {
            System.out.println("Thrown an error" + e.getMessage());
        }

初期化クラスで、必要に応じてコメントインおよびコメントアウトします。

でも。プログラムを実行するたびに、2 次元配列の内容 (mapArray書き込み時homeTiles、読み取り時) が異なります。私が(思って)書いたものと違うだけでなく、プログラムを開くたびに違う。

ご覧のとおり、さらに奇妙な点を明らかにする を出力しtoStringています。System.out単なる標準配列であるため、toString100% 役立つわけではありませんが、いくつかの異なる値の間を循環しているようです。ただし、toStringg同じ値を指定しても、表示される配列の内容は同じではありません。

a の例はtoString( here )hometiles:[[Lriseofthenecromancer.MapTile;@7681720a のドキュメントを見ると、末尾に ] がなく、形式が悪いようです。これが問題の手がかりなのか、単に配列が非常に大きく (数千のオブジェクト)、表示スペースの問題なのか (私は NetBeans を使用しています) なのか、私にはわかりません。Array.toString

なぜこれが変化しているのかについての洞察をいただければ幸いです。私の作業の前提は、配列をシリアル化するが内容はシリアル化しないということです。しかし、私には、a) その場合、b) もしそうなら、どうすればよいかわかりません。

編集:これをもう少し詳しく調べると、インスタンス変数がすぐに設定されていないようです。への呼び出しの直後にそれらをsetImage()印刷すると、それらはすべてゼロになり、呼び出し元のクラスから印刷すると、本来あるべき場所に表示されます。

4

1 に答える 1

-1

根本的な問題は、私が馬鹿だということでした。この特定のケースでの具体的な表現は、サブクラスがプライベート メソッドを継承できないことを忘れていたことです。そのため、assignImage呼び出しは行われておらず、イメージはセットアップされていませんでした。

これを見た人の時間を無駄にして申し訳ありません。かなり恥ずかしく思います。

于 2013-06-27T02:32:01.890 に答える