2015-03-31 70 views
0

我注意到一個奇怪的行爲,使用雙括號初始化時,初始化的對象序列化失敗雙括弧初始化和系列化

javax.jms.JMSException: Failed to serialize object 
at org.hornetq.jms.client.HornetQObjectMessage.setObject(HornetQObjectMessage.java:139) 

而一切罰款運行,否則

queueVO.setUser(new UserVO()); 
queueVO.getUser().setIndex("admin"); 

我知道這個語法糖導致創建一個匿名類,但我不明白爲什麼它打破了可序列化的合同。

有人可以解釋我在這裏發生了什麼?

+1

雙括號初始化是一個骯髒的黑客攻擊,可能會導致各種意想不到的問題。它不應該被使用。這不是一種語言功能;這是濫用匿名類。由於沒有序列化的原因 - 您的API可以序列化其他任意的匿名類嗎?你如何期望它在另一端反序列化它們? – 2015-03-31 07:50:21

+0

的根本原因是一個java.io.NotSerializableException,由hornetQ實現包裝它似乎我的用戶現在的類型MyTestClassType $ 1這確實不可序列化 – Gab 2015-03-31 07:57:42

+1

不,MyTestClassType $ 1從它的超類繼承'Serializable',但顧名思義,匿名內部類是一個內部類,並且具有對其外部實例的引用。當內部類實例被序列化時,它也會嘗試序列化外部實例。也許你現在明白了爲什麼「Double Brace Initialization」是一種反模式。這個隱藏的引用也可能導致內存泄漏... – Holger 2015-03-31 08:10:04

回答

2

創建的匿名類是不是靜態,所以有一個<SurroundingClass>.this,這未免太序列化,或者更糟的變成空的對象將被重新加載後。

一個解決方案是讓setter返回這個值,而不是void。然後你可以連鎖二傳手。

UserVO vo = new UserVO().setIndex("admin"); 
+0

確實'SurroundingClass'似乎由我的測試類類型,我真的不明白。我已經知道流利的語法,謝謝 – Gab 2015-03-31 07:58:56

+1

@Gab [this](http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class)可能會有所幫助。 – 2015-03-31 08:00:50

+0

好了,謝謝很多傢伙 – Gab 2015-03-31 08:02:56