2012-06-07 95 views
0

假設有兩個類,ObjectA和ObjectB。類對象A必須創建ObjectB類的對象如下的方法:如何存儲對一個類的所有對象的引用?

private ObjectB createObjectB() { 
    Object b = new ObjectB(); 
    return b; 
} 

我想跟蹤ObjectB所有實例。有什麼更好的方法來做到這一點?

  • 跟蹤類ObjectA中的所有對象爲ArrayList
  • ObjectB中的某些類變量。

每種方法的優缺點是什麼?如果我知道ObjectB對象只能通過ObjectA中的這一個方法創建,它是否會產生影響?

請注意,將只有一個ObjectA實例,但ObjectB的實例數量是可變的。

+1

這取決於您需要跟蹤對象的所有實例的原因。你的用例是什麼? – Jeffrey

+0

需要使用哪些參考? – n00begon

+0

爲了最大限度地獲取ObjectB實例的垃圾回收列表[** weak references **](http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html)應該保持;在那裏有一些微弱的參考文獻集,但不幸的是不在JSE中。 –

回答

0

如果只有一個ObjectA實例,它有一個createB方法,我會繼續在ObjectA實例本身的列表。但實際上我認爲這不重要。

public ObjectB createB(){ 
    Object B = new ObjectB(); 
    allBs.add(b); // assuming some sort of List 
    return b; 
} 

我很想知道你爲什麼要這樣做。根據您的應用程序和架構,您可能會遇到線程問題等等。

+0

如果ObjectB對象可以由多個類創建,並且每個類都想要遍歷它創建的對象,出於任何原因,保存僅包含這些對象的數組會更快。但是有時候我也會想把所有objectB對象的記錄寫入磁盤,所以有一組所有這些對象會很方便。但是每次創建一個對象時創建兩個引用需要的時間比一個長,並且我不知道檢查數組的每個對象中的字段(查看創建它的哪個類)的速度要慢得多,更小的陣列開始? – Ben

0

在ObjectB中保存一個列表是沒有意義的,但是如果需要對所創建的所有B對象進行引用,則ObjectA中的列表將是有意義的。

1

如果您想從代碼的不相關部分訪問所有創建的對象,只需要「跟蹤」以此方式創建的對象。否則1)創建的對象將被變量保存,因此您可以訪問它並且2)當沒有更多的對象引用(因此它是不可訪問的)時,垃圾收集器將最終清理內存。

如果做他們的跟蹤,記住,當你有集合中的對象,這可能會導致內存不足,錯誤GC無法釋放內存

+0

在會話的生命週期中創建objectB對象後,我不會銷燬它們,並且希望在會話結束時將它們輸出到數據庫或其他東西,所以將它們全部放在一個地方很方便。但我也想遍歷一個特定類創建的類,所以也可以很方便地保持這種方式。不知道最初是否要慢兩次寫入(並採用雙倍內存),還是遍歷一個列表來確定哪些需要對它們做些什麼? – Ben

+0

@Ben - 在這種情況下,可能最容易將兩個引用存儲到同一個對象中:一個用於數據庫,另一個用於創建它的類 – Attila

0

這取決於你需要實現什麼。如果ObjectB(這是一個壞名字,順便說一句)的實例能夠相互交談?如果是這樣,那麼您需要在該類中創建一個全局變量(即static字段),或者您必須將該列表保留在ObjectA中,並將其「注入」到ObjectB的每個實例中 - 這意味着您需要保留一個引用在這兩個地方。

如果ObjectB的實例不需要彼此交談,通常只要將列表保留在ObjectA即可。

但是大多數情況下,沒有必要保留一個列表。它甚至可能是危險的,因爲您必須確保列表不會增長,直到消耗完所有內存。

一般規則是:避免不必要的依賴關係。通過保留一個列表,你引入了一個有代價的依賴關係(例如,在維護中,你需要首先編寫代碼)。

永遠不要擔心你寫的東西的成本 - 很容易讓這些便宜的東西積累到一個非常昂貴的依賴關係中,這些東西會扼殺你。

+0

他們不需要彼此交談,但第三類想要隨時瞭解B類的所有實例。我想,如果第三類新創建了所有可能的位置,它可以訪問它們的每個列表以獲得它們全部的組合。看起來很混亂,但只是在一個地方只有一大堆好的東西。 – Ben

+0

從某種意義上說,'A'是'B'實例的工廠。您可以在'A'(壞)列表中保留一個列表,或者在創建新實例時發送一個事件。然後'A'可以包含一個對這些事件感興趣的監聽器列表('C'會自己註冊),然後'C'可以做任何想做的事情。那隻會引入一個便宜的依賴關係,因爲'A'不需要知道任何關於'C'和它需要的東西。 –

0

對我來說,它看起來像對象A和對象C是管理對象B實例的類。

我有一個類似的場景,我需要跟蹤不同的服務,它們是Base服務類的子類(對象B是我的例子中的基類)。

要創建/開始/停止/重新啓動/刪除這些服務我有2個經理類爲兩個不同的目的(如對象A和對象C在你的情況)。

在兩種管理器類我有一個HashMap

你可以有一個方法來停止/開始/創建/ destory /去除在類A或C它接受「名稱」的ob對象B B對象並啓動相應在對象B上執行操作。

作爲一種最佳實踐,在您的SessionContextListener中始終確保調用停止/刪除操作以刪除在此HashMap中添加的對象。

0

根據你對ObjectC所說的話,我會說ObjectA(和C)維護一個ObjectB數組是最有意義的。 (實際上,如果您希望添加和減去B,我建議使用某種集合而不是數組)。

然後,您可以創建一個方法來返回由A創建的B的數量,例如A.countB()

如果您發現自己需要創建B的總數並且不能使用A.countB()+ C.countB(),那麼您有兩個選擇:a B中的靜態映射關鍵是創建者對象(A,C或其他),並且該值是B的集合。

由於以下幾個原因,我會不鼓勵這樣做,主要是創建的對象會四處閒逛(所以沒有GC和潛在的內存問題)。

另一種方法是使用管理員類來創建和跟蹤B,並且在完成實例後非常小心取消引用。

相關問題