2011-08-09 18 views
6

संभव डुप्लिकेट आरंभ बनाम घोषणा पर आरंभ किया जा रहा:
Should I initialize variable within constructor or outside constructorकंस्ट्रक्टर्स में

मैं सोच रहा था, जो एक बेहतर अभ्यास और क्यों है। क्या मुझे घोषणा पर कक्षा के क्षेत्रों को शुरू करना चाहिए, या मुझे इसे निर्माता में करना चाहिए? यह देखते हुए कि यह एक साधारण एक-पंक्ति प्रारंभिक है।

class Dude 
{ 
    String name = "El duderino"; 

    Dude() { 
     // irrelevant code 
    } 
} 

बनाम

class Dude 
{ 
    String name; 

    Dude() { 
     name = "El duderino"; 

     // irrelevant code 
    } 
} 

संपादित करें: मैं स्थितियों में, जहां शैलियों में से एक प्रारंभकर्ता कोड को क्रियान्वित करने के मामले कि एक अपवाद फेंक सकती है में की तरह एक दूसरे के ऊपर प्राथमिकता दी जाएगी के बारे में पता कर रहा हूँ । मैं यहां जो बात कर रहा हूं वह ऐसे मामले हैं जब दोनों शैलियों बिल्कुल समकक्ष हैं। दोनों तरीके एक ही काम पूरा करेंगे। तब मुझे किस का उपयोग करना चाहिए?

उत्तर

4

तो सदस्य कर सकते हैं केवल एक एक्सेसर (एक "सेटर" विधि) के माध्यम से सेट किया जाना चाहिए, मैं पहली शैली पसंद करते हैं। यह एक संकेत प्रदान करता है कि प्रारंभिक मूल्य निर्माण पर डिफ़ॉल्ट है।

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

final class Dude { 

    private final String name; 

    Dude() { 
    this("El Duderino"); 
    } 

    Dude(String name) { 
    this.name = name; 
    } 

} 
+0

यह उचित लगता है। लेकिन मैं जो बात कर रहा था वह वे क्षेत्र हैं जिन्हें एक ही तरीके से शुरू किया जा रहा था, यानी रचनाकारों से प्राप्त डेटा का उपयोग नहीं किया जाएगा। उप-तत्वों को संग्रहीत करने के लिए एक खाली आंतरिक सूची प्रारंभ करना। क्या आप अभी भी इसे निर्माता में शुरू करेंगे? – amrhassan

+0

@महरसन - उस स्थिति में, जब मैं घोषित किया जाता हूं, तो मैं इसे प्रारंभ नहीं करूँगा, और मैं इसे 'अंतिम' घोषित करूंगा। – erickson

+0

मैं आपके उदाहरण में इसे 'अंतिम' बनाने का कारण देख सकता हूं, लेकिन अगर सेटटर 'सेटनाम (स्ट्रिंग नाम) 'था तो क्या होगा ... – knownasilya

0

पहला व्यक्ति आमतौर पर स्थैतिक चर प्रारंभ करने के लिए उपयोग किया जाता है और केवल उस उद्देश्य के लिए उपयोग किया जाना चाहिए।

इस मामले में, आपको दूसरी विधि का उपयोग करना चाहिए।

अगर मैं गलत हूं तो कृपया मुझे सही करें।

+0

पहला काम किसी भी स्थिर फ़ील्ड के लिए ठीक नहीं है। यह दूसरे के लिए एक सिंथेटिक चीनी है। – amit

+0

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

+0

मुझे स्थैतिक चर के लिए पहली शैली आरक्षित करने का कोई कारण नहीं दिखता है। क्या आप कोई तर्क दे सकते हैं? – erickson

0

स्थिरता के लिए कन्स्ट्रक्टर के अंदर चर घोषित करना सबसे अच्छा है। एक वैरिएबल को लूप या किसी अन्य स्टेटमेंट को प्रारंभ करने के लिए कुछ की आवश्यकता हो सकती है, जिसे किसी विधि के अंदर ऑपरेशन को रखे बिना घोषणा में नहीं किया जा सकता है।

इस नियम का अपवाद स्थैतिक चर है, जिसे निर्माता के बाहर घोषित किया जाना चाहिए।

+0

हम उन क्षेत्रों को प्रारंभ करने के लिए प्रारंभिक ब्लॉक का उपयोग कर सकते हैं जो अन्यथा केवल विधि या कन्स्ट्रक्टर के अंदर आरंभ किए जाएंगे। – emory

0

सिंगल लाइन घोषणाओं में जटिल प्रारंभिक तर्क शामिल नहीं हो सकता है।

आप के रूप में एक चर को प्रारंभ करते हैं:

class AnotherClass 
{ 
    MyClass anObject = new MyClass(); //MyClass() throws a checked exception. 
} 

तो आप पाएंगे कि आप एक पंक्ति में प्रारंभिक मूल्य प्रदान नहीं कर सकते।

एक निर्माता का उपयोग करना::

class AnotherClass 
{ 
    MyClass anObject; 

    AnotherClass() 
    { 
     try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/} 
    } 
} 

एक प्रारंभ ब्लॉक का उपयोग करते हुए आप, कि काफी स्पष्ट रूप से एक निर्माता के अंदर चला जाता है (या एक गैर स्थिर प्रारंभ ब्लॉक में) एक ब्लॉक में इस तरह के कोड डालने की आवश्यकता होगी:

class AnotherClass 
{ 
    MyClass anObject; 

    { 
     try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/} 
    } 
} 

मुझे लगता है कि बाद के कम से समझा जा सकता कोड के लिए बनाता है, घोषणा और प्रारंभ के रूप में एक दूसरे से अलग कर रहे हैं, और प्रारंभ एक निर्माता डेवलपर द्वारा कोडित में नहीं होती है (हालांकि वहाँ कार्यावधि में कोई अंतर नहीं है)।

फ़ील्ड के प्रारंभ में शामिल अन्य जटिल दिनचर्या के लिए भी यही है।उदाहरण के लिए, एक Array या एक Collection प्रारंभ और सरणी/संग्रह कुछ डिफ़ॉल्ट मान पर की सामग्री को निर्धारित करने के लिए यदि आप चाहते हैं, तो आप एक निर्माता के अंदर ऐसा करना चाहिए:

class AnotherClass 
{ 
    Integer[] integers; 

    AnotherClass() 
    { 
     this.integers = new Integer[10]; 
     for(Integer integer: integers) 
     { 
      integer = Integer.MIN_VALUE; 
     } 
    } 
} 
+1

असल में कोई भी प्रारंभकर्ता ब्लॉक का उपयोग भी कर सकता है, इसलिए इस मामले में कन्स्ट्रक्टर एकमात्र संभावित तरीका नहीं है – Voo

+0

हां, हालांकि यह बहुत भ्रमित हो सकता है। लेकिन यह मेरी राय है। संपादित करेंगे –

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