1

ファイルからオブジェクトまで、さまざまな種類のオブジェクトを読み取りたいのですがArrayList、それらはすべて、クラス Advertisement を拡張するクラスのインスタンスです。私はこのコードを試しています:

ArrayList <Advertisement> ads = new ArrayList<Advertisement>();
ObjectInput input2 = new ObjectInputStream(
    new BufferedInputStream(new FileInputStream("ads.ser")));

//break from this method at this point
ads = (ArrayList<Advertisement>) input2.readObject(); 

問題は 3 行目/最後の行にあります。adstype の variable 内のオブジェクトを読み取らずArrayList<Advertisement>、さらに、メッセージなしでこのメソッドを中断します。

編集: try-catch ブロックを削除しました。以前に実行する必要がありましたが、まだ解決策がわかりません。スタックトレース:

java.io.InvalidClassException: Kiado; local class incompatible: stream classdesc serialVersionUID = -1393576200767336208, local class serialVersionUID = -841663850423605586
    at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at java.util.ArrayList.readObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at Main.beolvasas(Main.java:30)
    at Main.startup(Main.java:57)
    at Main.main(Main.java:633)
4

2 に答える 2

1

スタック トレースが得られたので、問題は明らかです。オブジェクトをファイルにシリアル化した瞬間から、 class に変更を加えていますKiado。そのため、オブジェクトをファイルにシリアル化したときのように、現在のクラスはクラスと互換性がなくなりました。

クラス (およびそのすべてのスーパークラス) のフィールドの番号と名前を変更していない場合は、クラスに次の変数宣言を追加するだけで、再度互換性を持たせることができます。

private static final long serialVersionUID = -1393576200767336208;

少なくとも 1 つの (非一時的な) フィールドを追加、削除、または名前変更した場合、新しいクラスを古いクラスと互換性を保つことができますが、手間がかかります。そして、私たちはあなたを助けるために変更の性質を知る必要があります.

お気づきのように、ネイティブ シリアル化は壊れやすく、モデルを変更するのが難しいため、個人的には長期保存にネイティブ シリアル化を使用することは避けたいと思います。たとえば、XML や JSON など、より読みやすく移行可能なファイル形式を使用します。

于 2013-04-20T16:56:16.787 に答える
0

次のようなコードはありますか?

catch(<WheteverException> e)
{
   // nothing here
}

その場合は、次の手順を実行します。

  1. // nothing hereをに変更e.printStackTrace();
  2. try/catch を削除し、コンパイラが指示した場合にのみ追加し直し、コンパイラが追加するように指示した例外のみを追加し直します (たとえば、 do not do catch(Exception e).
于 2013-04-20T16:10:28.877 に答える