2016-11-15 1 views
6

の代わりに生成されたserialVersionIDの利点シリアライズ可能なクラスのserialVersionUIDについて、同僚と話し合いました。彼は常にserialVersionUID = 1Lで始まり、クラスに大きな変更があったときに1ずつインクリメントします。1L、2L、

JDKクラスは常に、より複雑な使用するように見えるが、java.lang.Stringクラスのような serialVersionUIDs生成:

private static final long serialVersionUID = -6849794470754667710L; 

を今私の同僚は、1L、2Lのような非常に簡単serialVersionUIDの対serialVersionUIDが、この種の利点について質問します、3L ...?

また、SOFで検索しましたが、回答が非常に満足できません(例:Why generate long serialVersionUID instead of a simple 1L?)。

私の意見では、生成されたIDを使用する利点は、 '古い'クラスのバージョンに関する情報は必要ないということです。しかし、手動でIDをインクリメントするときは、これまでのところ最高の値を知る必要があります。これは(現在のserialVersionUIDを見て、それを1だけ増やすだけで)些細なことかもしれませんが、より大きなソフトウェアプロジェクト、より大きな開発チーム、または分散環境ではもっと複雑になる可能性があります。

+2

クラスに重大な変更が加えられた場合にそれを増やすと、これらの変更によって新しいバージョンのクラスが古いバージョンと互換性がなくなります。その場合、serialVersionUIDをまったく持たないことは、最も冗長で簡単な解決策です。 –

+4

serialVersionUIDは、クラスのバージョンではなく、シリアライズされたフォーム*の互換バージョンを追跡するのに最適です。クラスは、状態がシリアル化された形式から書き込まれ、読み込まれる方法に何ら変更することなく、広範囲に変更することができます。クラスがシリアライズされたフォームと互換性がある限り、serialVersionUIDを変更する理由はありません(シームレスに指定するのがベストプラクティスです)。 – scottb

+0

人は私を間違えないでください、私は直列化の仕組みがどのように動作するのか知っていますし、問題はありません。私は、生成されたserialVersionUIDsと増分されたものの利点または不利な点について疑問に思います。 –

答えて

-1

これは興味深い質問です。私は分かりません。

SUIDはパブリックAPIの一部です。 のコントロール(JDKなど)の外部で使用されるAPIを公開すると、この 番号を互換性を失うことなく変更することはできません。

したがって、数字を使用する利点はありません 1Lではなく32432544354343Lのように。

しかし、社内開発のために、私は、1Lのような数字で始まる の小さな利点を参照してください。

たちはRMIクライアント・サーバ・アプリケーションの3瓶考えてみましょう:

  • client.jarのを
  • api.jarので
  • server.jar
  • api.jarの

クライアントとサーバーで使用される 曲、アルバム、などのビジネスクラスです。 シリアライズ可能です。

これらのクラスのうちのいくつかについては、SUIDを とし、リリース後にSUIDを2Lに増やすために、これらのクラスのうちの1つの の内部フォーマットを変更します。

クライアントとサーバーコンポーネントの両方に、新しいapi.jar を含める必要があります。 私たちが間違いを犯してクライアントまたは サーバを新しいapi.jar依存関係で更新するのを忘れた場合、デシリアライズ時には例外 が発生します。例外のメッセージには、互換性のないSUIDが になります。

ここで、番号1Lと2Lはメッセージにあります。 2L> 1L、 したがって、コンポーネントが古いapi.jarを使用していることがわかります。 IDEが123434534553Lと654642646363Lのような数字を生成した場合、古いapi.jarを使用するコンポーネントは ではありません。

しかし、 のような新しいJDKクラスでさえ、LocalDateは の代わりに123434534553Lのような数字を使います。 Apacheのコモンズランには、例えば、 のような組み合わせがあるようです。 FastDateParser.javaは単純な3Lを使用します。

https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/time/FastDateParser.java

奇妙な...

+0

変更が互換性がない場合は、いずれにせよ、逆シリアル化で例外が発生します。本当に必要でないかもしれない場合を含め、意図的にこの例外を引き起こすために 'serialVersionUID'を変更することはあまり意味がありません。 – EJP

1

生成されたものを使用する利点は、それが野生にserialVersionUIDずに脱出した場合、それはクラスの以前のバージョンと互換性があることです。

あなたの同僚はそれを増やすことは間違いだと言っています。 serialVersionUIDは、クラスが回復不能に変更されたことに同意した時点でのみ変更し、意図的に直列化の非互換性を導入する必要があります。これが本質的に発生する時期はまれであり、クラスの継承またはメンバフィールドの型を互換性のない方法で変更する場合に限定されています。 Serializableクラスを作ることに決めた場合は、体制を受け入れているはずです。

+0

バージョン管理(例えば、クラスに新しいフィールドを追加するなど)を扱うには、独自のバージョンフィールドを持つaproachを考慮する必要があります。ここに示すように:http://stackoverflow.com/questions/3678136/managing-several-versions-of-serialized-java-objects#answer-14946099 – szymond

+0

@szymondまたは継承。 – EJP

関連する問題