2012-08-16 12 views
5

के लिए अलग-अलग ऑब्जेक्ट संदर्भ मैंने हाल ही में किसी अन्य वर्ग से कक्षा का अद्वितीय उदाहरण प्राप्त करने के बारे में पूछा है। किएक ही (?) ऑब्जेक्ट

public class View 
{ 

    // I'm accessing my instance of Application again 

    public static Application application = Application.getSharedApplication(); 

    // This method should return my unique instance of Application 

    public Application getApplication() 
    { 
     return application; 
    } 

} 

समस्या है main:

(How to get specific instance of class from another class in Java?)

तो, मैं इसे काम करने के लिए कोशिश कर रहा हूँ:

मेरे Application:

public class Application 
{ 

    // I will always have only one instance of Application 

    private static Application _application; 

    // Every instance of Application (one in my case) should have its own View 

    private View view; 

    // Constructor for new instance of Application 

    private Application() 
    { 
     view = new View(); 
    } 

    // Getter for my unique instance of Application 

    public static Application getSharedApplication() 
    { 
     if (_application == null) 
      _application = new Application(); 
     return _application; 
    } 

    // Main class 

    public static void main(String[] args) 
    { 
     // So I'm accessing my instance of Application 
     Application application1 = getSharedApplication(); 

     // Here is object reference 
     System.out.println(application1); 

     // And now I'm accessing the same instance of Application through instance of View 
     Application application2 = application1.view.getApplication(); 

     // Here is object reference 
     System.out.println(application2); 
    } 

} 

मेरे View विधि अलग आता है वस्तु संदर्भ।

[email protected] 
[email protected] 

मेरे कोड में क्या गलत है?

+0

यह एक एकमात्र और वैश्विक राज्य के अन्य रूपों का उपयोग करता है :), कि क्या यह गलत है। –

+0

जब आपको सिंगलेट्स की आवश्यकता होती है तो enums का उपयोग क्यों न करें। –

उत्तर

7

यह इस प्रकार होता है:

  • कार्यक्रम पहले कॉल Application application1 = getSharedApplication();
  • बदले में स्थिर तरीका है जिसके new Application() कॉल कॉल - कि कॉल देखें वर्ग है, जो Application का एक सदस्य है लोड करने के लिए की जरूरत है।
  • व्यू क्लास लोड हो गया है और इसके स्थिर सदस्य को प्रारंभ किया गया है और getSharedApplication(); चलाता है (ध्यान दें कि इस चरण में, _application अभी भी शून्य है)। इससे new Application() भी

आपके पास अब 2 एप्लिकेशन उदाहरण हैं।

ध्यान दें कि यदि आप अपने मुख्य की पहली पंक्ति के रूप में View v = new View(); जोड़ते हैं, तो आपके पास केवल एक उदाहरण है (जो दृश्य के स्थिर चर से एक बार लोड हो जाता है)। यह समझ में आता है जब आप इसके बारे में कड़ी मेहनत करते हैं लेकिन बहुत सहज नहीं है ...

+0

सुंदर। यह उदाहरण पृष्ठ पर जाना चाहिए "क्यों सिंगलटन लगभग हमेशा एक बुरा विचार है"! – Jochen

+0

वैश्विक स्थिति (स्थैतिक चर) के बारे में तर्क करना मुश्किल है, खासकर जब चक्रीय संदर्भ हैं! – assylias

+1

सिंगलेट्स एक बुरा विचार नहीं है, लेकिन वे यहां पर लागू होने पर खराब तरीके से कार्यान्वित किए जा सकते हैं। –

4

ऐसे प्रश्नों का सामान्य उत्तर है: एक डीबगर का उपयोग करें! उदाहरण के लिए, आप Application के निर्माता में ब्रेक पॉइंट सेट कर सकते हैं, अपना प्रोग्राम चला सकते हैं, और जब कन्स्ट्रक्टर दूसरी बार निष्पादित होता है तो स्टैक का निरीक्षण करता है।

आप ऐसा करते हैं, तो आप कुछ इस तरह ध्यान दें होगी:

Application.<init>() line: 21 
Application.getSharedApplication() line: 31 
View.<clinit>() line: 59  
Application.<init>() line: 23 
Application.getSharedApplication() line: 31 

है, दृश्य साझा आवेदन से पहले साझा आवेदन प्राप्त करना चाहता है पूरी तरह से निर्माण किया गया है (और बाद से पहले संग्रहीत किया जाता है स्थिर क्षेत्र में)।

0

GetSharedAplication() विधि सिंक्रनाइज़ किए गए कीवर्ड का उपयोग करना चाहिए। अन्यथा अगर दो थ्रेड पहले कथन ब्लॉक में प्रवेश कर सकते हैं और दोनों अलग-अलग चर बनाते हैं।

मुझे यकीन नहीं है कि यह क्या हो रहा है। डीबग/प्रिंट स्टेटमेंट्स को हर जगह जोड़ने का प्रयास करें ताकि आप वास्तव में क्या हो रहा है उसका पालन कर सकें।

+2

इस उदाहरण में केवल एक धागा है। – assylias

+0

@assylias मुझे पता है, लेकिन अगर वह सिंक्रनाइज़ नहीं किया गया है तो वह बाद में परेशानी के लिए पूछ रहा है। –

+0

आप एक उचित बिंदु बनाते हैं - मैं बस इतना कह रहा हूं कि यह इस मुद्दे का कारण नहीं है। – assylias

1

आप की तरह

नीचे
public static Application getSharedApplication() { 

    if(_application == null) 
    { 
     _application = new Application(); 
     view = new View(); 
    } 

आप केवल एक उदाहरण बनाया जा रहा है मिलेगा देखें का आरंभीकरण को बदलते हैं। कारण है कि एप्लिकेशन पूरी तरह से प्रारंभ होने से पहले आप दृश्य उदाहरण बना रहे हैं। चूंकि क्लास का अनुरोध पहली बार किया जाता है जब स्थैतिक चर लोड होते हैं इसलिए यह व्यवहार हो रहा है।

वैसे भी मुझे पता चला कभी नहीं है कि इस धन्यवाद :)

+0

एचएम, यह काम करता है! :) –

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