0

次のクラスを使用して、シリアル化によって 3 次元配列をコピーするつもりです。

public class Serializer {

    public byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }

    public Object deserialize(byte[] bytes) throws IOException,
            ClassNotFoundException {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        return o.readObject();
    }
}

次に、メイン コードで次のように記述します。

int array[][][] = new int[param][][];
Serializer s = new Serializer();
byte [] b = s.serialize(array);
Object arrayCopy = s.deserialize(b);

ただし、最後の行に「Unhandled exception type ClassNotFoundException」というエラー メッセージが表示されます。

また、Object arrayCopy を int[param][][] に変換する方法がわかりません。これが最終的な目的です。これどうやってするの?

ありがとう

4

1 に答える 1

1

ただし、最後の行に「Unhandled exception type ClassNotFoundException」というエラー メッセージが表示されます。

メソッドdeserializeは 2 つのチェック済み例外 (IOException、ClassNotFoundException) をスローします。これらは、try-catch ブロックを使用してコードを呼び出す際に処理する必要があります。

また、Object arrayCopy を int[param][][] に変換する方法がわかりません。これが最終目的です。

オブジェクトをキャストするには、式の RHS の先頭に目的の型 (int[][][]) を角かっこで囲みます。あなたのケースでは、メソッドから返されるオブジェクトのタイプが実際にはわからないため、これは安全でないキャストであることに注意してください。deserialize

例外処理とキャストの両方を組み合わせると、メイン コードは次のようになります。

try {
    int array[][][] = new int[param][][];
    Serializer s = new Serializer();
    byte [] b = s.serialize(array);
    Object arrayCopy = (int[][][]) s.deserialize(b);
} catch(IOException ioe) {
    // ... handle this
} catch(ClassNotFoundException cnfe) {
    // ... handle this
}

より安全なキャスティング

安全でないキャストを回避したい場合は、ジェネリックを使用して、deserializeメソッドの予想される戻り値の型を示すことができます。逆シリアル化されたオブジェクトが実際に目的のクラス型であったことを、メソッド自体で検証する必要もあります。このようなもの:

public class Serializer {

    public <T> byte[] serialize(T obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }

    public <T> T deserialize(Class<T> clazz, byte[] bytes) throws IOException,
            ClassNotFoundException {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        final Object raw = o.readObject();
        if (raw.getClass().isAssignableFrom(clazz))
            return clazz.cast(raw);
        else
            throw new IllegalArgumentException(
                    "Byte data does not represent a class of type " + clazz);
    }
}

メソッドの変更点は次のdeserializeとおりです。

  • (メソッド レベルの) ジェネリック パラメーターを追加するT
  • Class<T>返されると予想される型を表す追加のパラメーター ( ) を追加します。
  • メソッドに検証を追加して、逆シリアル化されたオブジェクトが実際に目的のクラスのインスタンスであることを確認します
  • 逆シリアル化されたオブジェクトが実際には目的のクラスのインスタンスではない場合に備えて、不正な引数の例外を追加します

これらの変更を使用する場合は、メイン コードで も処理する必要がありますIllegalArgumentException

于 2013-02-21T12:10:41.653 に答える