2011-10-25 16 views
4

インスタンスの初期化子ブロックと共に匿名インスタンス化を使用すると、「シリアル化可能なクラスは、long型の静的なfinalVersionUIDフィールドを宣言しません」というコンパイル時の警告が表示されます。匿名の初期化 - 奇妙なシリアル化の警告

ここに私の言いたいことがあります。のは、私はArrayListのをインスタンス化すると同時に、そのようにそれに何かを追加したいとしましょう:

ArrayList<Object> arrayList = new ArrayList<Object>(){{add(new Object());}}; 

私はこれをコンパイルする場合、すべてがOKですが、私はserialVersionUIDのフィールド不足している警告が表示されます。今ArrayListはすでにserializableを実装していて、private static final long serialVersionUIDを持っていますが、なぜ私はそれを使用してそのフィールドが「消え去っている」ように見え、宣言していないという警告が表示されますか?

+1

これは単なる愚かです。今日、Javaのシリアライゼーションはほとんど使用されていませんが、そのような一般的な警告は不当です。そして**私はIDEを**準拠していないコンパイラ**と呼んでいるEclipseユーザーを乗り越えることはできません。 – irreputable

+0

関連:[明白なserialVersionUIDは有害だと思っていますか?](http://stackoverflow.com/questions/419796/explicit-serialversionuid-considered-harmful) –

+0

@irreputableこれを抑制するアノテーションはありませんか?私は、チェックされていないキャストのためにそうすることができれば、確かにUIDのようなものは無視できると思うでしょう。 –

答えて

7

匿名クラスを作成すると、実際にArrayListが拡張され、Serializableインターフェイスを継承します。

すべてSerializableクラスにはserialVersionUIDがあるので、クラスの異なるシリアル化バージョンを区別できます。匿名型は新しいクラスであるため、異なるバージョンを区別できるようにIDを付けることをお勧めします。

+3

これはArrayListクラスを拡張するのと同じです。拡張クラスには "add"を呼び出すイニシャライザブロックがありますが、別のクラスです。(ArrayListからSerializableを継承しているため)独自のserialVersionUIDが必要です。それは私が匿名のクラスを作成していたために私には分かりませんでした。 –

+1

@AndreiBodnarescuまさに。匿名クラスは別のクラス(あなたの場合は 'ArrayList')から拡張する新しいクラスを作成するための文法的な砂糖です。 –

+2

@AndreiBodnarescu正確に。これは言ってやりましたが、コレクションプライミングにこの二重括弧構文を使うのは、今ではArrayListを持っていないのですが、むしろあいまいな問題を引き起こす曖昧なサブクラスがあるので避けてください。おそらくあまりにも多くのチャンスをあなたがそれらの問題にぶつかることはありませんが、あなたがそうすると、それは大事にするでしょう。冗長かもしれませんが、すべての 'add()'文を書いたり、配列を初期化してから、それを使ってリストを作成すればよいでしょう。 –

2

基本的にサブクラスであるものを作成するためです。そのようなサブクラスには、独自のシリアルバージョンUIDが必要です。 JPanelのようなものをサブクラス化するときも同じことが起こります。シリアライゼーションを必要としない(デ)必要がなければ、それはひどい問題ではありません。

0
new ArrayList<Object>() { 

    { 
     add(new Object()); 
    } 

}; 

あなただけのインスタンスが、最初ArrayListのサブクラス(匿名)を定義して、サブクラスをインスタンス化されていません。それは静的だ、そのあなたの匿名のサブクラスによって継承されていないので、ArrayListprivate static final long serialVersionUIDがあるにもかかわらず

。それで、そのフィールドが欠落しています。

関連する問題