2011-05-30 143 views
4

假設您有一個java對象,是否可以檢測到存在的位置circular references inside that java object檢測對象中的循環引用

我想聽聽是否有圖書館來解決這個問題。

在此先感謝。

回答

1

有點側面的答案,但如何使用net.sf.json.JSONObject.fromObject(...)其中checks for circular references和拋出一個異常,如果有任何被發現。另外,如果需要,您可以配置庫以不同方式處理循環引用。您必須爲循環關係中存在的那些類成員編寫getter,因爲這是JSONObject用來創建JSON的。

+0

謝謝。即使我只是嘗試使用XStream JSON,我得到了這個:com.thoughtworks.xstream.core.TreeMarshaller $ CircularReferenceException:但我不知道它在哪裏循環引用。有任何想法嗎? – olidev 2011-05-30 12:50:46

+0

對於這個json-lib,你可以註冊一個[CycleDetectionStrategy](http://json-lib.sourceforge.net/apidocs/net/sf/json/util/CycleDetectionStrategy.html)並訪問「重複」對象。也許可以做類似的XStream,但由於某種原因,XStream API目前不適合我,所以我無法檢查! – andyb 2011-05-30 13:13:00

+1

謝謝。任何想法,如果我只是試過:JSONObject jsonObject = JSONObject.fromObject(myModel);我得到了這個異常:線程「main」中的異常java.lang.NoClassDefFoundError:org/apache/commons/lang/exception/NestableRuntimeException謝謝! – olidev 2011-05-30 13:29:05

0

你不需要任何庫。這是簡單的廣度優先搜索alghoritm和反射API。當然你可以嘗試找到一個實現這個alghoritm的庫。

0

這似乎是一個簡單的任務編碼。使用Java反射API來抓取Java對象的圖形並收集訪問的對象。如果你訪問已經在該集合中的對象,那意味着必須有一個電路。抓取使用BFS或DFS算法。

4

當心,這不是一件容易的事,但你已經知道了,對嗎? ;)

在Java中有IdentityHashMap的實現,它被設計爲在這種情況下使用。

+0

+1提及'IdentityHashMap' – Waldheinz 2011-05-30 12:44:29

2

從概念上講很簡單,但實施起來可能相當複雜。

首先,很大程度上取決於您正在處理的對象類型。如果只有少量的對象類,並且「擁有」這些類並且可以修改它們以添加「搜索自己」代碼,那麼它變得更容易:

向每個類添加一個接口並實現「自己搜索「每個班級的方法。該方法接收一個對象列表,並返回一個返回碼。該方法將自己的地址與列表中的每個對象進行比較,如果匹配則返回true(即找到循環)。然後(如果不匹配)它將自己的地址添加到列表中,然後調用它包含的每個對象引用的「搜索自己」方法。如果這些調用中的任何一個產生了真實的返回代碼,則返回該代碼,否則返回false。 (這是一個「深度優先遞歸」搜索。)

如果您沒有「擁有」這些類,那麼您必須使用反射來實現上述算法,而無需修改這些類。

還有其他的搜索算法可以使用 - 「寬度優先」和深度優先的各種非遞歸版本,但它們都代表了堆存儲,堆棧之間的一種或另一種排序存儲和性能。

+0

(IdentityHashMap將是實現對象列表的一個好方法。) – 2011-05-30 13:05:19

+0

也可以用一個位掩碼替換對象列表,用給定對象的第一次搜索對象時在掩碼中的位置(使用全局計數器)。 – 2011-05-30 13:36:53

+0

當然,您可以通過向對象添加字段來最好地實現算法。每個對象都需要一個bool,兩個整數,以及一個指向您的「搜索自己」界面對象的指針。不需要遞歸,也沒有吹堆的危險。將在aN + bM時間內執行,其中N是對象的總數,M是對象間指針的總數。 – 2011-05-30 23:15:17