21

serialVersionUIDシリアル化されたJavaオブジェクトの生成を判別する方法はありますか?

問題は、を明示的に指定せずにオブジェクトをシリアル化したことserialVersionUIDです。現在、逆シリアル化プロセスはクラスの非互換性について不平を言っています。ただし、互換性がなくなるような方法でクラスを変更しませんでした。serialVersionUIDしたがって、オブジェクトデータに格納されているクラスでを指定するだけで十分だと思います。これを行うにはserialVersionUID、シリアル化されたデータからを読み取る必要があります。

4

9 に答える 9

28

これは私のために働く:

long serialVersionUID = ObjectStreamClass.lookup(YourObject.getClass()).getSerialVersionUID();

それがあなたにも役立つことを願っています。

于 2014-11-08T22:15:18.077 に答える
25

クラスのserialversionUIDを見つける簡単な方法があります-

serialversionUID- について言及するのを忘れたクラスがあるとします。

import java.io.Serializable;

public class TestSerializable implements Serializable {

}

これだけやって-

serialver -classpath . TestSerializable

これは印刷します-

static final long serialVersionUID = 5832063776451490808L;

serialver は JDK に付属するユーティリティです。

于 2009-08-24T13:14:35.767 に答える
12

これを行うには、 ObjectInputStreamを拡張します。

public class PrintUIDs extends ObjectInputStream {

  public PrintUIDs(InputStream in) throws IOException {
    super(in);
  }

  @Override
  protected ObjectStreamClass readClassDescriptor() throws IOException,
      ClassNotFoundException {
    ObjectStreamClass descriptor = super.readClassDescriptor();
    System.out.println("name=" + descriptor.getName());
    System.out.println("serialVersionUID=" + descriptor.getSerialVersionUID());
    return descriptor;
  }

  public static void main(String[] args) throws IOException,
      ClassNotFoundException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    List<Object> list = Arrays.asList((Object) new Date(), UUID.randomUUID());
    oos.writeObject(list);
    oos.close();
    InputStream in = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream ois = new PrintUIDs(in);
    ois.readObject();
  }

}

メソッドによって返された記述子を置き換えることで、シリアル化されたすべてのデータを読み取ることができると思いますが、試したことはありません。

于 2009-08-24T12:46:58.103 に答える
5

シリアル化されたビット (必要に応じてヘッダー) に関連付けられたメタデータがあります。値がどの位置にあるかがわかっている場合は、メタデータから値を読み取ることができます (SerialVersionUIDクラス名などの他の情報と共にそこに書き込まれます)。

この記事が役立つと思います: Java シリアライゼーション アルゴリズムが明らかにしました。

ビットは「平文で」書き込まれることに注意してください (ストリームを明示的に暗号化しない限り) SerialVersionUID.

于 2009-08-24T13:06:39.217 に答える
1

オブジェクトのシリアル化には、指定された文法があります。

http://java.sun.com/javase/6/docs/platform/serialization/spec/serialTOC.htmlの 6.4 章を参照してください。

これを使用すると、シリアル化されたオブジェクトの SerialVersionUID を特定できるはずです。

于 2009-08-24T12:26:56.363 に答える
0

それはまさにあなたがすべきことです-あなた自身を指定してくださいstatic final long serialVersionUID

Serializableのドキュメントにそれに関するセクションがあります。

あなたがserialVersionUIDIを指定しない限り、@ WMRが示唆するように、ストリームを解読する以外にそれを取得する簡単な方法があるとは思わない。

于 2009-08-24T12:24:30.530 に答える
0

シリアル化されたオブジェクトの serialVersionUID を取得するはるかに簡単な方法があります。異なるシリアル バージョン uid を持つ同じクラスに apache commons serialization utils を使用してシリアル化解除し、多かれ少なかれ例外メッセージを読み取ります。

org.apache.commons.lang.SerializationException: java.io.InvalidClassException: my.example.SerializableClass; ローカル クラスに互換性がありません: ストリーム classdeser serialVersionUID = -1、ローカル クラス serialVersionUID = -2

于 2016-07-04T10:41:49.020 に答える