2013-04-09 2 views
7

मैं सी ++ के लिए अधिक उपयोग किया जाता हूं। एक वर्ग के सभी उदाहरणों (यह है कि उपयोगकर्ता द्वारा बढ़ाया जा सकता है एक पुस्तकालय वर्ग है) की एक सूची प्राप्त करने के लिए, मैं आमतौर पर इस तरह की वस्तुओं के सभी संदर्भ के साथ एक स्थिर कंटेनर:जावा: कक्षा के सभी उदाहरणों के संदर्भों को कैसे संग्रहीत किया जाए?

#include <list> 
class CPPClass; 

class CPPClass { 
    public: 
    CPPClass() { 
     objList.push_back(this); 
    } 
    ~CPPClass() { 
     objList.remove(this); 
    } 

    private: 
    static std::list<CPPClass *> objList; 
}; 

std::list<CPPClass *> CPPClass::objList; 

मुझे क्या करना चाहिए कैसे जावा में वही? मैं कुछ चिंताएं हैं:

  • किसी ने मुझे बताया कि एक से अधिक classloaders हो सकता है, और कहा कि समस्याओं
  • वहाँ जावा में कोई नाशक है के कारण हो सकता है, तो कैसे संदर्भ सूची से हटा दिया जाएगा?
  • यदि संदर्भ हटाए नहीं जाते हैं, तो इन वस्तुओं को कब कचरा इकट्ठा किया जाता है?
+1

स्टोर [कमजोर संदर्भ] (http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html) ऑब्जेक्ट में उन्हें कचरा इकट्ठा करने की अनुमति देने के लिए। – GriffeyDog

उत्तर

4

आसान चीजें पहले: एकाधिक क्लासलोडर आपको तब तक कोई समस्या नहीं पहुंचाएंगे जब तक कि आप गैर-मानक प्रतिनिधिमंडल पैटर्न (कस्टम क्लासलोडर के साथ) का उपयोग न करें। यदि आपके पास ऐसा गैर-मानक क्लासलोडर है, तो आप एप के एक परिस्थिति के अलग-अलग हिस्सों को CPPClass वर्ग (एक अलग क्लासलोडर से प्रत्येक संस्करण) के विभिन्न संस्करणों का उपयोग कर सकते हैं। यह विभिन्न मुद्दों है (! आप एक ClassCastExceptionCPPClass को CPPClass से कास्टिंग प्राप्त कर सकते हैं), लेकिन यह अपने स्थिर संग्रह प्रभावित नहीं होना चाहिए; प्रत्येक CPPClass का अपना स्वयं का, अलग संग्रह होगा।

अगला बात: निर्माता से संग्रह करने के लिए वस्तुओं न जोड़ें। एक निर्माता से this संदर्भ लेना स्मृति मॉडल समस्याओं का कारण बन सकता है। इसके बजाए, आपको एक स्थैतिक फैक्ट्री विधि बनाना चाहिए जो ऑब्जेक्ट बनाता है और फिर इसे अलग-अलग संग्रह में जोड़ता है। यह संग्रह निश्चित रूप से थ्रेड-सुरक्षित भी होना चाहिए।

अंत में, कोर प्रश्न। यदि प्रत्येक ऑब्जेक्ट किसी अन्य ऑब्जेक्ट के बराबर नहीं है (यानी, यदि आपने Object.equals ओवरराइड नहीं किया है), तो आप WeakHashMap का उपयोग ऑब्जेक्ट्स के साथ ऑब्जेक्ट्स के साथ कर सकते हैं। वर्ग equals ओवरराइड करता है, तो आप WeakReference रों है, जो आप (, सम्मिलित पर सूची, आदि पुन: प्राप्त करने पर) सुविधाजनक समय पर काटना कर सकते हैं का एक संग्रह बना सकते हैं। एक वीक रेफरेंस उस ऑब्जेक्ट को रोक नहीं पाएगा जो इसे जीसीड होने से संदर्भित करता है - यह जीसी होने के बाद get से null लौटाएगा।

लेकिन अगर मैं थोड़ा सा संपादकीय कर सकता हूं, तो इस तरह के "समाधान" अक्सर एक बीमार परिभाषित ऑब्जेक्ट लाइफसाइक्ल पर संकेत देते हैं, जिसमें अन्य रखरखाव के मुद्दे हैं।यह बेहतर हो सकता है यदि आपकी ऑब्जेक्ट्स Closeable लागू करती हैं या कोड के लिए एक समान तरीका है जो यह घोषणा करने के लिए करता है कि यह उनके साथ समाप्त हो गया है।

+0

मुझे लगता है कि मैं 'बराबर' विधि पर भरोसा नहीं कर सकता हूं, क्योंकि उपयोगकर्ता जो भी चाहें कर सकता है ... जब तक कि मैं इसे अंतिम नहीं कर सकता, लेकिन मुझे लगता है कि यह बहुत ही सीमित होगा ... इसके अलावा, क्या क्या मैं 'वीक हैशमैप' के मूल्य में डालूंगा? तो, मुझे लगता है कि मुझे 'वीकएरेलेलिस्ट' जैसी कुछ चीज़ों के साथ छोड़ दिया गया है (क्या ऐसी कोई चीज है?) या कंटेनर को लागू करना (मुझे लगता है कि जावा में इसे संग्रह कहा जाता है?) स्वयं। 'बंद करने योग्य' को कार्यान्वित करना, हालांकि, प्रोग्रामिंग के एक अच्छे और परिचित तरीके से वापस जाने जैसा लगता है, लेकिन क्या यह आदर्श जावा समाधान होगा? –

+1

क्लोजेबल लागू करना (या यदि आप जावा 1.7 पर हैं तो ऑटोक्लोसेबल और [प्रयास-संसाधनों] का उपयोग करना चाहते हैं (http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) निश्चित रूप से है मूर्खतापूर्ण जावा। जेडीके कक्षाओं के बहुत सारे ऐसा करते हैं - इनपुटस्ट्रीम, जेडीबीसी कक्षाएं, आदि। यदि आप अपने संग्रह का उपयोग करना चाहते हैं, तो मैं 'सूची <वीक रेफरेंस >' पर शुरू करूंगा। मैं स्क्रैच से अपना खुद का संग्रह लागू नहीं करूंगा, बस एक जेडीके संग्रह का उपयोग करें और मैन्युअल रूप से बाएं वीक संदर्भों को शुद्ध करने के लिए इसे पार करूँगा। – yshavit

0

आप वास्तव में सूची को स्थिर बना सकते हैं, बस यह सुनिश्चित कर लें कि आप इसे ठीक से शुरू भी कर सकते हैं।

List<CPPClass> objlist; 
static { 
    objlist = new List<CPPClass>(); 
} 

या ऐसा कुछ ऐसा करना चाहिए।

यदि आप संदर्भ को नहीं हटाते हैं, तो उसे कचरा कभी नहीं मिलेगा क्योंकि कचरा कलेक्टर मान लेगा कि ऑब्जेक्ट अभी भी उपयोग में है।

ऐसा कुछ ऐसा है जो एक विनाशक जैसा लगता है: विधि finalize। लेकिन क्योंकि इस विधि को केवल कचरा कलेक्टर द्वारा बुलाया जाता है और आप इसे स्वयं का उपयोग नहीं कर सकते हैं, यह आपके लिए उपयोग नहीं करेगा। इस तरह से कचरा कलेक्टर वस्तु अगर WeakReference केवल संदर्भ है कि रहता है मुक्त होगा -

1

बल्कि एक वस्तु के लिए एक संदर्भ के भंडारण की तुलना में, एक WeakReference वस्तु के लिए दुकान।

संबंधित मुद्दे