2011-01-13 12 views
5

मैं व्यक्तिगत रूप से उदाहरण प्रारंभकर्ताओं की तरह हूं - मैं उन्हें संग्रह जैसे चीजों को डिफ़ॉल्ट मान निर्दिष्ट करने के लिए उपयोग करता हूं ताकि रचनाकारों को लिखते समय मुझे उन्हें हर बार एक ही डिफ़ॉल्ट मान निर्दिष्ट करने की आवश्यकता नहीं है। यह मेरे लिए काफी सुरुचिपूर्ण लगता है - परेशान एनपीई के पॉपिंग अप से बचाता है और डुप्लिकेट कोड से बचाता है। एक निजी विधि उतनी अच्छी नहीं लगती है क्योंकि ए) यह अंतिम फ़ील्ड को मान असाइन नहीं कर सकता है, बी) इसे कोड में कहीं और चलाया जा सकता है और सी) विधि को प्रत्येक कन्स्ट्रक्टर की शुरुआत में स्पष्ट रूप से बुलाया जाना चाहिए।उदाहरण प्रारंभकर्ताओं को बुरी शैली माना जाता है?

हालांकि, मैंने जिन लोगों के साथ बात की है, उनके साथ फ्लिप पक्ष यह है कि वे भ्रमित हैं, कुछ लोग कोड पढ़ते हैं, वे समझ नहीं सकते हैं कि वे क्या करते हैं या जब उन्हें बुलाया जाता है और इस तरह वे हल करने से अधिक समस्याएं पैदा कर सकते हैं।

क्या इन प्रारंभकर्ताओं का उचित उपयोग प्रोत्साहित किया जाना चाहिए या इससे बचा जाना चाहिए? या यह एक "अपने स्वयं के" मामले में है?

+3

कोई भी भाषा सुविधा "अच्छी" या "खराब" नहीं है - सब कुछ ऐसी स्थिति है जिसमें यह वास्तव में चमकता है। मुझे लगता है कि एक बेहतर सवाल यह है कि "किस परिस्थितियों में उदाहरण प्रारंभकर्ताओं से बचा जा सकता है या इस्तेमाल किया जा सकता है?" – templatetypedef

+1

आप लगभग हमेशा संग्रह प्रकारों के फ़ील्ड को 'अंतिम' होना चाहते हैं, जो उन लोगों के लिए एनपीई समस्या को हल करते हैं। –

उत्तर

3

यह आपके कोड के जावा पाठकों के बारे में ज्ञान के स्तर पर उदाहरण के लिए निर्भर करता है, और विकल्प व्यावहारिक हैं या नहीं।

विकल्प हैं: हर निर्माता में

  • इनलाइन। यदि कई रचनाकार हैं, तो यह DRY का उल्लंघन करता है।
  • सभी कन्स्ट्रक्टर एक ही निर्माता के प्रतिनिधि हैं, और उस कोड को उसमें डाल दें।यदि रचनाकार गैर-तुच्छ हैं, और विभिन्न तर्क लेते हैं, तो उन्हें एक नया कन्स्ट्रक्टर लिखने की आवश्यकता हो सकती है जो सभी क्षेत्रों के मूल्यों को अपने तर्कों में प्राप्त करता है। यदि कई फ़ील्ड हैं, तो यह काफी लंबा हो सकता है (और पढ़ने में मुश्किल है, क्योंकि यह स्पष्ट नहीं है कि कौन सा मूल्य किस क्षेत्र को सौंपा जा रहा है)
  • सभी रचनाकार एक इनिट विधि का आह्वान करते हैं। इस तरह के अंतिम फ़ील्ड असाइन नहीं कर सकते हैं। शायद विधि को ओवरराइड होने से रोकना चाहिए। शायद इसे कई बार बुलाए जाने से रोकना चाहें।

चूंकि प्रारंभकर्ता असामान्य हैं, इसलिए आपको केवल उन्हें प्राथमिकता देना चाहिए जब उनका उपयोग करने के लिए स्पष्ट लाभ हो। मेरा सबसे हालिया उपयोग था:

private final Collator collator = Collator.getInstance(); 
{ 
    collator.setStrength(Collator.SECONDARY); 
} 

कई रचनाकारों के साथ कई अलग-अलग तर्क सूचियों और आधे दर्जन अन्य क्षेत्रों के साथ एक वर्ग में।

0

आप पैरामीटर के साथ एक कन्स्ट्रक्टर का उपयोग कर सकते हैं और यह कन्स्ट्रक्टर निजी सेटर्स को कॉल करता है। और एक डिफ़ॉल्ट कन्स्ट्रक्टर को लागू करने के बजाय जो उस निर्माता को डिफ़ॉल्ट मानों के साथ कॉल करता है। यदि आप गुणों के लिए डिफ़ॉल्ट मान असाइन करना चाहते हैं, तो इसे घोषणा में करें।

उदाहरण और स्थैतिक प्रारंभकर्ता मैट्रिस या क्यूब्स जैसे जटिल डेटास्ट्रक्चर में प्रवेश करने के लिए अच्छे हैं।

वैसे, एक अंतिम संपत्ति को अक्सर स्थिर कहा जाता है।

+2

निजी सेटर्स? इसका क्या मतलब होगा? दूसरा, एक डिफ़ॉल्ट कन्स्ट्रक्टर आमतौर पर एक ही कक्षा के भीतर एक और कन्स्ट्रक्टर को कॉल नहीं करना चाहिए। अंत में, "अंतिम" गुण पारंपरिक अर्थ में "स्थिरांक" नहीं हैं। सेट होने के बाद उन्हें बदला नहीं जा सकता है, लेकिन प्रत्येक इंस्टेंस में रनटाइम पर अपना स्वयं का गैर-परिवर्तनीय मान सेट हो सकता है। जावा दुनिया में "निरंतर" का अर्थ आम तौर पर "स्थिर अंतिम" होता है और आमतौर पर डिजाइन-समय पर सेट किया जाता है। –

1

मैं वास्तव में उनका उपयोग नहीं करता हूं लेकिन एक मामला मैं उन्हें उपयोगी देख सकता हूं, जब आपके पास कई रचनाकार होते हैं, स्वयं को (यह (..)) नहीं बुलाते हैं, जिन्हें कुछ सामान्य प्रारंभिक तर्क साझा करने की आवश्यकता होती है, और बनाने की कोई आवश्यकता नहीं होती है इसके लिए एक विशिष्ट निजी विधि। ओह और केवल जगह मैं का उपयोग जल्दी से उदाहरण के लिए एक पंक्ति का मैप्स, जैसे में प्रारंभ के लिए उदाहरण initializers हैं:

Map<String,String> m = new HashMap<String,String>(){{ 
    put("a","b"); 
    put("c","b"); 
    put("d","b"); 
}}; 

के एक अंतरफलक

interface A { 

    Map<String,String> PROPS = Collections.unmodifiableMap(new HashMap<String,String>(){{ 
     put("a","b"); 
     put("c","b"); 
     put("d","b"); 
    }}); 
} 

मान लीजिए एक मानचित्र आरंभ करने के लिए उपयोगी हो सकता है अभी भी ऐसा करने से आप हैश मैप के एक अज्ञात उप-वर्ग के साथ समाप्त हो जाते हैं ...

1

अपने कन्स्ट्रक्टर को अधिभारित करना बेहतर है और जितना चाहें उतने कन्स्ट्रक्टर विविधताएं हैं। सबसे अच्छा उदाहरण जावा की ऐरेलिस्ट है। इसमें दो रचनाकार हैं। एक जो एक तर्क के रूप में पूर्णांक लेता है और दूसरा एक डिफ़ॉल्ट कन्स्ट्रक्टर होता है। आप डिफ़ॉल्ट निर्माता पर एक नज़र डालें, तो यह वास्तव में एक स्थिर मान के साथ एकल तर्क निर्माता कॉल 10.

List<Object> x = new ArrayList<Object>(); //Creates with default capacity 10 
List<Object> y = new ArrayList<Object>(40); //Creates with the specified capacity 40 
1

मैं रहना होगा कि वे पसंद करते हैं। लेकिन अन्य प्रतिक्रियाओं के आधार पर ऐसा प्रतीत होता है कि यह "अपने प्रत्येक के लिए" अधिक हो सकता है। मुझे उन्हें पसंद है क्योंकि यह संबंधित जानकारी को एक साथ रखता है। एक मूल्य घोषित करने और इसे निर्माता में स्थापित करने के बजाय, आप इसे एक ही स्थान पर कर सकते हैं।

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