たとえば、HttpServlet を拡張するクラスを作成したいですか? クラスに serialVersionUID が必要であるとコンパイラが警告します。このオブジェクトが決してシリアル化されないことがわかっている場合、それらの警告を抑制するためにオブジェクトを定義するか、注釈を追加する必要がありますか?
あなたは何をしますか、なぜですか?
たとえば、HttpServlet を拡張するクラスを作成したいですか? クラスに serialVersionUID が必要であるとコンパイラが警告します。このオブジェクトが決してシリアル化されないことがわかっている場合、それらの警告を抑制するためにオブジェクトを定義するか、注釈を追加する必要がありますか?
あなたは何をしますか、なぜですか?
Java のベスト プラクティスはわかりませんが、シリアル化が決して起こらないと主張している場合は、スローする writeObject メソッドを追加できると思います。次に、警告があなたに当てはまる可能性がないことを知って安全に、警告を抑制します。
そうしないと、誰かが将来、親クラスを介してオブジェクトをシリアル化し、最終的にデフォルトのシリアル化された形式になる可能性があります。
ID を追加するのは面倒に思えます。本当にやりたいのはシリアル化ではないからです。呼び出し元がオブジェクトをシリアライズしないことを期待するということは、HttpServlet があなたのクラスのものであることを呼び出し元が「知っている」ことを期待することを意味します。ポリモーフィズムの違反は、シリアル化してはならない Serializable オブジェクトを持っていることで頭に浮かびます。少なくともできることは、不注意な呼び出し元にそれを知らせることです。
インスタンスをシリアライズする予定がない場合は、SuppressWarning を追加してください。
生成されたシリアル ID は少し危険な場合があります。意図的にシリアル番号を付け、シリアル化および逆シリアル化するために保存されていることを示唆しています。クラスが変更されたアプリケーションの新しいバージョンでは、シリアル番号を更新するのを忘れがちです。クラス フィールドが変更されている場合、デシリアライズは失敗します。SuppressWarning を持つことで、少なくとも、このクラスをシリアル化するつもりはなかったことがコードの読者に伝えられます。
Eclipse に脅かされて、コードが煩雑になるのは嫌です!
serialVersionUID が欠落している場合に警告を生成しないように Eclipse を構成するだけです。
@ Steve Jessop に感謝します。それは 5 行のコードでした...ほとんど面倒ではありませんでした。
@SuppressWarnings("serial")
問題のクラスのすぐ上に追加しました。
このメソッドも追加しました:
private void writeObject(ObjectOutputStream oos) throws IOException {
throw new IOException("This class is NOT serializable.");
}
うまくいけば、それがスティーブの意図したことです:)
このオブジェクトがシリアル化されることがわかっている場合でも、serialVersionUID を生成する必要はありません。これは、Java が自動的にオブジェクトを生成し、変更を自動的に追跡するため、シリアル化が常に正常に機能するためです。自分が何をしているのかを知っている場合にのみ生成する必要があります (下位シリアル化の互換性、手動の変更追跡など)。
したがって、ほとんどの場合、警告を抑制することが最善かつ最も安全な解決策であると言えます。
serializable を実装するすべてのクラスに SVUID を生成することをお勧めします。理由は簡単です。あなたや第三者によっていつ連載されるかはわかりません。サーブレットをシリアル化する多くのサービスを構成できます。すべての IDE に対して、テンプレートを 1 つ生成するか、テンプレートを使用して svuid = 1L を設定するプラグインが存在します。
Swing クラスをサブクラス化するたびに、それをシリアル化するつもりはないことがわかっているので、その警告は私を夢中にさせますが、そのばかげた警告があります。でもええ、私は Eclipse にそれを生成させました。
場合によります。
異なるコンパイラを使用してソースコードを複数回コンパイルする場合、コンパイルされたコードに異なるserializationIdが含まれる可能性があり、これによりシリアル化が中断されます。次に、コードで明示的に定数serializationIdに固執する必要があります。静的かつ最終的で、クラスごとである必要があります(継承できません)。
ただし、常に特定のコンパイラを使用してコードをコンパイルし、常にすべてのVMにコードを一度にデプロイする場合は、厳密なバージョンチェックが必要であり、実行中のコードのバージョンが1つだけであることを確認する必要があります。その場合は、警告を抑制するだけです。したがって、VMが正常にデプロイされず、古いバージョンのコードを実行している場合は、逆シリアル化されたオブジェクトではなく、シリアル化中に例外が発生する可能性があります。これは私の場合です。以前は非常に大規模なクラスターがあり、デプロイメントの問題を見つけるために厳密なバージョンチェックが必要です。
とにかく、デフォルトのシリアル化はプロトコルバッファや節約に比べて非常に遅く、言語間の相互運用性をサポートしていないため、おそらく可能な限りシリアル化を避ける必要があります。
Eclipse に ID を生成させます。早くて簡単。警告は無視されるべきではありません。また、オブジェクトを/has/シリアライズする必要がある場合に備えて、多くの問題を回避できます。
serialVersionUID を省略すると、Java はコンパイル時にクラス用に生成します (コンパイルごとに変更されます)。
オブジェクトを逆シリアル化する場合、逆シリアル化されたオブジェクトの serialVersionUID が jvm 内のクラスのそれと比較されます。それらが異なる場合、それらは互換性がないと見なされ、例外がスローされます。これは、たとえば、プログラムをアップグレードして古いクラスを逆シリアル化した後に発生する可能性があります。
serialversionUID には常に 1L を使用します。(デフォルトで生成されたものと比較して) 害はなく、後で id をインクリメントして互換性を壊すオプションも残されています。
詳細な説明を得るには、このリンクに従ってください: http://technologiquepanorama.wordpress.com/2009/02/13/what-is-use-of-serialversiouid/
アプリケーションがシリアライズしないことがわかっている場合は、アプリケーション全体で警告を抑制してください。これは、javac コマンド ライン引数を使用して実行できます。
javac -Xlint -Xlint:-serial *******
このようにして、「シリアル」以外のすべての警告が表示されます。IDE と Maven/SBT/Gradle などのビルド ツールは、それで問題なく動作します。