2010-09-07 55 views
7

就像標題所說的,有沒有辦法檢查一個對象是否可序列化,如果沒有,在運行時就這麼做?你可以在運行時使對象可序列化嗎?

+0

如果對象不是序列化的,它可能是一個很好的理由:比如,這是毫無意義的序列數據庫連接。 – 2010-09-07 16:29:33

+1

不是Java Object Serialization的序列化格式是否工作?我正在考慮使用反射和JSON或XML來序列化對象的解決方案。從其他評論,它聽起來像你的要求是使對象成爲一個字符串,這將做到這一點。 – 2010-09-07 17:10:04

+0

這個問題非常廣泛,主要是因爲它沒有提到你所有的設計限制。 (例如,你需要一個字符串序列化格式。) – jpaugh 2016-05-05 14:39:02

回答

11

簡答題 - 沒有。

較長的答案 - 是的,使用字節碼操作,例如與asm。但是你應該真的考慮這是否需要。序列化是一個嚴重的問題(有效的Java對序列化一整章)

順便說一句,有選擇性地對二進制序列化,不需要執行Serializble(在評論中指出雅各)對象:

  • XML - java.beans.XMLEncoder.encode(..)是xml版本ObjectOutputStream
  • JSON - 像Jacskon,Gson這樣的框架讓你用一行序列化一個對象。
+0

+1包括適當的警告。 – DJClayworth 2010-09-07 16:35:47

1

正如其他人所說...簡短的回答是

號您可以絕對的界面在運行時通過使用如在http://download.oracle.com/javase/6/docs/technotes/guides/reflection/proxy.html描述代理對象添加到任何舊的對象。這也包括java.io.Serializable。但是,爲了使代理對象有用,它必須保持對原始對象的內部引用,這在您的情況下不會實現Serializable。你的代理對象可以被序列化的唯一方法是將原始對象的內部引用作爲一個瞬態字段,這對你來說不會有太大好處。

此外,在檢查您的評論後,它看起來像Java序列化絕對不是你想要的,你真的只想序列化爲一些字符串格式。其他人已經提出了各種解決方案,但IMO如果你想最少量的大驚小怪,那就用XStream吧:http://x-stream.github.io/tutorial.html

+0

代理是由接口創建的,而不是一個類。 – Bozho 2010-09-07 16:32:00

+0

@Bozho - 該部分在我鏈接到的文檔中有詳細介紹。如果他還沒有使用Interface來多態地(sp?)引用他的對象,那麼需要在其代碼庫中進行一些更改。 – whaley 2010-09-07 16:45:47

+1

他的原始對象是InvocationHandler的成員,它也是序列化的,將會失敗。 – Bozho 2010-09-07 16:52:59

0

哇。爲什麼你需要在運行時檢查它?在編譯時確保它不是更容易嗎?使用這樣的代碼。

public void someMethod(Serializable serializable){ 
} 

或者你可以使它更復雜。

public interface SerializableInterface implements Serializable{ 
// bla-bla 
} 

public void someMethod(SerializableInterface serializable){ 
} 
0

除了現有很好的答案,另一個問題是你是否特別需要的Java序列化的具體框架,或者只需要能夠序列化對象。 對於後者,有比JDK默認的更多的選擇;對於許多用例來說,替代方案比JDK更好。

如果您不特別需要JDK,那麼使用基於JSON或XML的序列化通常是一個不錯的選擇。

+0

我在查看序列化的原因是因爲我想將一個對象轉換爲一個字符串(通過字節數組)以存儲和傳輸,因爲外部因素它必須是字符串。我已經看到了幾個如何使用序列化轉換爲字節流以最終捕獲對象作爲String的例子,但是如果對象不可序列化,該怎麼辦也沒有。我理解某些對象不需要序列化的必要性,但在這種情況下,開發人員可以自行決定。 – 2010-09-07 16:52:20

+0

好吧,那你肯定不想使用JDK Serializable。我會建議使用JSON序列化(如傑克遜,請參閱http://wiki.fasterxml.com/JacksonInFiveMinutes)。結果更具可讀性,並且更加脆弱。 Serializable的主要問題在於版本控制非常困難,所以它是堅持結果的反模式(例如,閱讀Josh Bloch的解釋)。它不可讀,或者(不像xml或json)。序列化本身並沒有什麼錯,但是Serializable很少是正確的。 – StaxMan 2010-09-08 02:05:57

0

在運行時檢查?當然。 「if(someObject instanceof Serializable)...」。

您想在運行時更改對象的定義嗎?很少有很好的理由想要這樣做。也許有辦法通過反思來做到這一點,但我從來沒有理由想要做這樣的事情。你想達到什麼目的?

0

如果有人確實真的需要在運行時使用字節碼進行操作。隨着庫Javassist可以做到這一點:

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("mypackage.MyClass"); 
cc.addInterface(pool.get("java.io.Serializable")) 
相關問題