2009-07-14 8 views
5

मैं वर्ग के वर्ग से कक्षा के एक उदाहरण को तुरंत चालू करना चाहता हूं।Class.forName() का उपयोग कर Instantiate सिंगलटन ऑब्जेक्ट?

यहाँ (।। Class.forName() newInstance() का प्रयोग करके) समस्या है: मुझे लगता है कि उदाहरण के एक सिंगलटन होना चाहता हूँ .. मैं सिवाय इसके कि newInstance एक सिंगलटन पद्धति का उपयोग कर ऐसा कर सकता है, के लिए डिफ़ॉल्ट निर्माता कॉल एक वर्ग, और एक सिंगलटन के साथ, वह कन्स्ट्रक्टर "निजी" होना चाहिए ..

क्या कोई समाधान है? मैं एक कम सुरुचिपूर्ण तरीका के बारे में सोच सकता है यह करने के लिए (एक लुकअप तालिका के रूप में एक hashmap का उपयोग कर ..), लेकिन एक बेहतर समाधान पसंद करेंगे ..

धन्यवाद,

+0

मैंने अभी भी आपका प्रश्न दो बार पढ़ा है और इसका पालन नहीं किया है ... शायद अन्य लोग करेंगे लेकिन मैंने सोचा था कि मैं आपको बता दूंगा ... –

+2

आपको इसकी आवश्यकता क्यों है? – akarnokd

+0

एफवाईआई: http: //developers.sun।कॉम/लर्निंग/जावावाइनलाइन/2008/पीडीएफ/टीएस -6623.pdf पेज 31. – akarnokd

उत्तर

1

तुम एक enum इस्तेमाल कर सकते हैं और है उनमें से प्रत्येक के लिए नामित एक हैश मैप। और इसकी सही सलामत

package tests; 
public class EnumSingleton { 
    public static void main(String[] args) throws Exception { 
     Class<?> c = Class.forName("tests.Singleton1"); 
     Operation instance = Operation.class.cast(c.getEnumConstants()[0]); 
     System.out.println(instance.getTHEAnswer()); 

     c = Class.forName("tests.Singleton2"); 
     instance = Operation.class.cast(c.getEnumConstants()[0]); 
     System.out.println(instance.getTHEAnswer()); 
    } 
} 
interface Operation { 
    int getTHEAnswer(); 
} 
enum Singleton1 implements Operation { 
    INSTANCE; 
    @Override 
    public int getTHEAnswer() { 
     return 42; 
    } 
} 
enum Singleton2 implements Operation { 
    INSTANCE; 
    @Override 
    public int getTHEAnswer() { 
     return 84; 
    } 
} 

: या आप कुछ निर्भरता इंजेक्शन ढांचे (? Guice) इस्तेमाल कर सकते हैं कुछ की एक सिंगलटन पाने के लिए

संपादित ठीक है, मैं में भी एक कोड नमूने के साथ कूद। संपादित करें और अब कुछ अर्थ है।

8

एक क्लासिक सिंगलटन में एक स्थिर getInstance() विधि भी है - कॉल करें कि नयाInstance() का उपयोग करने के बजाय प्रतिबिंब के माध्यम से। हाँ, यह अधिक काम है, लेकिन यह है कि यह कैसे है ...

या आप setAccessible() का उपयोग निजी कन्स्ट्रक्टर को कॉल करने के लिए कर सकते हैं, लेकिन आप सिंगलटन को तोड़ देंगे और नरक में जाएंगे।

तीसरा, आप सिंगलटन को पूरी तरह से रखने से बच सकते हैं और एक बेहतर हल (आमतौर पर वहां) पाते हैं।

+0

एस/आमतौर पर/हमेशा/ –

7

आप वर्ग की स्थिर फैक्ट्री विधि का संदर्भ प्राप्त करने के लिए प्रतिबिंब का उपयोग कर सकते हैं, और उसके बाद उसे आमंत्रित कर सकते हैं। कारखाने विधि सिंगलटन पैटर्न को लागू कर सकता है

Class c = Class.forName("test.MyClass"); 
Method factoryMethod = c.getDeclaredMethod("getInstance"); 
Object singleton = factoryMethod.invoke(null, null); 

और फिर

public class MyClass { 

    private static MyClass instance; 

    private MyClass() { 
     // private c'tor 
    } 

    public static synchronized MyClass getInstance() { 
     if (instance == null) { 
     instance = new MyClass(); 
     } 
     return instance: 
    } 
} 

चेतावनी: सिंगलटन डिजाइन पैटर्न अपने दीर्घकालिक स्वास्थ्य के लिए हानिकारक हो सकता है।

+0

अच्छा, फिर भी मैं जानना चाहता हूं कि ओपी नाम से सिंगलटन क्यों चाहता है? – akarnokd

+0

शायद वे वसंत का पुन: आविष्कार कर रहे हैं। – skaffman

+0

लूत के छोटे सिंगलेट्स! –

2

आपको ऑब्जेक्ट को बनाने वाले आपके सिंगलटन क्लास का विधि नाम जानना होगा। यदि यह उदाहरण है "इंस्टेंस()" कहा जाता है जिसे आप

Class c = Class.forName("MySingleton"); 
Method m = c.getDeclaredMethod("instance",null); 
MySingleton singleton = m.invoke(null,null); 
0

क्या आप इसके बजाय एक स्थिर फैक्ट्री विधि के अस्तित्व पर भरोसा कर सकते हैं? यह किसी तरह के नामकरण सम्मेलन पर भरोसा करेगा, लेकिन यह काम करेगा।

नीचे पंक्ति: यदि किसी वर्ग को सिंगलटन होने के लिए जाना जाता है तो उसे उस पुलिस के लिए जिम्मेदारी होनी चाहिए। इसलिए इसे पैटर्न के कुछ कार्यान्वयन के अनुरूप होना चाहिए, और यदि आप इस तरह के वर्गों में गतिशील चयन चाहते हैं तो आपको "फैक्टरी" दृष्टिकोण की भविष्यवाणी करने में सक्षम होना चाहिए।

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