web-dev-qa-db-ja.com

serialVersionUIDを使用するか、警告を抑制しますか?

たとえば、HttpServletを拡張するクラスを作成したいですか?コンパイラは、クラスにserialVersionUIDが必要であることを警告しています。このオブジェクトがシリアル化されないことがわかっている場合、これらの警告を抑制するために、オブジェクトを定義するか、注釈を追加する必要がありますか?

あなたは何をしますか、なぜですか?

66
Okami

Javaベストプラクティスはわかりませんが、シリアル化は決して行われないと主張している場合は、スローするwriteObjectメソッドを追加できます。それはおそらくあなたに適用できないという知識。

そうしないと、将来誰かが親クラスを介してオブジェクトをシリアル化し、次のデフォルトのシリアル化された形式になる可能性があります。

  • フォームはコードの異なるバージョン間で互換性がありません。
  • これが事実であるという警告を抑制しました。

IDを追加することは、本当にやりたいことがシリアル化されないため、ごまかしのように聞こえます。呼び出し元がオブジェクトをシリアル化しないことを期待するということは、HttpServletがあなたのクラスのものであるときに「知る」ことを期待することを意味します。ポリモーフィズムの違反は、シリアライズされてはならないSerializableオブジェクトを持っていることに対するあなたの頭にあります。

27
Steve Jessop

インスタンスをシリアル化する予定がない場合は、SuppressWarningを追加します。

生成されたシリアルIDは少し危険です。意図的にシリアル番号を付与し、シリアル化および逆シリアル化するために保存することをお勧めします。クラスが変更されたアプリケーションの新しいバージョンでシリアル番号を更新するのを忘れがちです。クラスフィールドが変更されている場合、逆シリアル化は失敗します。 SuppressWarningがあれば、少なくともこのクラスをシリアル化するつもりはないことをコードの読者に伝えます。

18
Benno Richters

私は、Eclipseに恐怖を感じてコードを混乱させることを拒否します!

不足しているserialVersionUIDに関する警告を生成しないようにEclipseを構成します。

14
ykaganovich

これについての彼の答えを@ Steve Jessopに感謝します。それは5行のコードでした...ほとんど面倒ではありませんでした。

問題のクラスのすぐ上に@SuppressWarnings("serial")を追加しました。

このメソッドも追加しました:

private void writeObject(ObjectOutputStream oos) throws IOException {
   throw new IOException("This class is NOT serializable.");
}

うまくいけば、それがスティーブが意味したことです:)

9
Mike

このオブジェクトがシリアル化されることがわかっていても、Javaが自動的に生成し、変更を自動的に追跡するので、シリアル化は常に正常に機能するため、serialVersionUIDを生成する必要はありません。何をしているかを知っている場合にのみ生成する必要があります(後方シリアル化の互換性、手動の変更追跡など)。

そのため、ほとんどの場合、警告を抑制することが最善かつ最も安全なソリューションであると言えます。

6
serg

SVUIDをevery serializableを実装するクラスに生成するとよいでしょう。その理由は簡単です。あなたneverそれはあなたまたは第三者によっていつシリアル化されるかを知っています。サーブレットをシリアル化する多くのサービスを構成できます。すべてのIDEは、プラグインを生成するか、単にテンプレートを使用してsvuid = 1Lを設定するプラグインが存在します。

4

Swingクラスをサブクラス化するたびに、knowをシリアル化することはありませんが、その愚かな警告があるためです。しかし、ええ、Eclipseに生成させます。

3
Paul Tomblin

EclipseにIDを生成させます。早くて簡単。警告は無視されません。また、オブジェクトをシリアル化する必要が生じた場合、多くのトラブルを回避できます。

2
xmjx

詳細な説明を入手するには、このリンクに従ってください: http://technologiquepanorama.wordpress.com/2009/02/13/what-is-use-of-serialversiouid/

2
harshit

場合によります。

異なるコンパイラを使用してソースコードを複数回コンパイルすると、コンパイルされたコードに異なるserializationIdが含まれ、シリアル化が中断される可能性があります。次に、コード内で明示的に定数serializationIdに固執する必要があります。クラスごとに静的でfinalである必要があります(継承不可)。

ただし、常に特定のコンパイラでコードをコンパイルし、常にすべてのVMにコードをワンショットでデプロイする場合、おそらく厳密なバージョンチェックが必要であり、実行中のコードのバージョンが1つだけであることを常に確認する必要があります。その場合、警告を抑制する必要があります。したがって、VMが正常にデプロイされず、コードの古いバージョンを実行している場合、デシリアライズされたオブジェクトをクイクするのではなく、シリアライズ中に例外が発生する可能性があります。非常に大きなクラスターがあり、展開の問題を見つけるために厳密なバージョンチェックが必要です。

とにかく、デフォルトのシリアル化はプロトコルバッファやスリフトと比較して非常に遅く、言語間の相互運用性をサポートしていないため、可能な限りシリアル化を避ける必要があります。

2
Daniel

SerialVersionUIDを省略すると、Javaはコンパイル時にクラス用に生成されます(コンパイルごとに変わります)。

オブジェクトをデシリアライズするとき、デシリアライズされたオブジェクトのserialVersionUIDは、jvm内のクラスのserialVersionUIDと比較されます。それらが異なる場合、互換性がないと見なされ、例外がスローされます。これは、たとえばプログラムをアップグレードして古いクラスを逆シリアル化した後に発生する可能性があります。

SerialversionUIDには常に1Lを使用します。 (デフォルトで生成されるものと比較して)害はなく、IDをインクリメントすることで、後で互換性を壊すオプションを残します。

2
Glever

アプリケーションが物事をシリアル化しないことがわかっている場合は、アプリケーション全体で警告を抑制します。これは、javacコマンドライン引数を使用して実行できます。

javac -Xlint -Xlint:-serial *******

これにより、「シリアル」以外のすべての警告が表示されます。 IDE-sおよびMaven/SBT/Gradleなどのビルドツールは、それで問題なく動作します。

1
VasiliNovikov