2011-10-25 78 views
4

我想知道爲什麼當我使用一個匿名實例和一個實例初始化塊時,我得到一個「可序列化的類沒有聲明long類型的靜態最終serialVersionUID字段」編譯時警告。匿名初始化 - 奇怪的序列化警告

這是我的意思。比方說,我想實例化一個ArrayList和同時添加的東西給它,像這樣:

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

如果我編譯這一切都是確定,但我得到的serialVersionUID領域缺少警告。現在ArrayList已經實現了可序列化,並且有一個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類,然後THAT擴展類有調用「add」的初始化塊,但它是一個不同的類,它需要它自己的serialVersionUID(因爲它從ArrayList繼承Serializable)。由於我創建了一個匿名類,這對我來說並不明顯。 –

+1

@AndreiBodnarescu準確無誤。匿名類只是用於創建從另一個類擴展的新類的語法糖(在你的情況下,'ArrayList')。 –

+2

@AndreiBodnarescu準確。說了這麼多,使用這種雙括號語法來收集啓動是不鼓勵的,因爲現在你並沒有真正擁有一個ArrayList,而是一些模糊的子類,這可能會在稍後導致一些模糊的問題。你遇到這些問題的可能性不大,但是當你這樣做時,它會成爲一個頭疼的人。它可能是冗長的,但最好只寫所有的'add()'語句或初始化一個數組,然後使用它創建列表。 –

2

因爲你創建的是本質上是一個子類。這樣的子類需要自己的串行版本UID。當你像JPanel一樣子類化時,也會發生同樣的事情。如果你不需要(de)序列化,這不是一個可怕的問題。

0
new ArrayList<Object>() { 

    { 
     add(new Object()); 
    } 

}; 

你不只是實例,但首先定義的ArrayList一個子類(匿名),然後實例化的子類。

即使有在ArrayList一個private static final long serialVersionUID,因爲它是靜態,它不是由您的匿名子類繼承。所以它缺少這個領域。