2012-11-28 12 views
49

के साथ अंतिम परिवर्तनीय असाइनमेंट क्योंकि मुझे विश्वास है कि यह एक अच्छा प्रोग्रामिंग अभ्यास है, मैं अपने सभी (स्थानीय या उदाहरण) चर final बना देता हूं यदि वे केवल एक बार लिखा जाना चाहते हैं।कोशिश/पकड़

हालांकि, मैं नोटिस जब एक चर काम एक अपवाद फेंक कर सकते हैं चर अंतिम नहीं कहा बना सकते हैं:

final int x; 
try { 
    x = Integer.parseInt("someinput"); 
} 
catch(NumberFormatException e) { 
    x = 42; // Compiler error: The final local variable x may already have been assigned 
} 

वहाँ एक अस्थायी चर का सहारा के बिना यह करने के लिए कोई तरीका है? (या यह अंतिम संशोधक के लिए सही जगह नहीं है?)

+1

मुझे संदेह है कि आप इसे अस्थायी चर के बिना कर सकते हैं। – NPE

+8

'अंतिम int x = makeX();' निश्चित रूप से। (फ़ंक्शन में प्रयास करें) –

+2

चौंकाने वाला कि जेडीके [अभी भी 'tryParse'' नहीं है (http://stackoverflow.com/questions/1486077/java-good-way-to-encapsulate-integer-parseint) । –

उत्तर

44

ऐसा करने का एक तरीका अस्थायी चर (गैर- final) अस्थायी चर प्रस्तुत करना है, लेकिन आपने कहा था कि आप ऐसा नहीं करना चाहते थे।

एक और तरीका है एक कार्य में मिली कोड के दोनों शाखाओं ले जाने के लिए है:

final int x = getValue(); 

private int getValue() { 
    try { 
    return Integer.parseInt("someinput"); 
    } 
    catch(NumberFormatException e) { 
    return 42; 
    } 
} 

किया जाए या नहीं इस व्यावहारिक है सटीक उपयोग के मामले पर निर्भर करता है।

सभी में, जब तक x एक उपयुक्त-स्कोप्ड स्थानीय चर है, तो सबसे व्यावहारिक सामान्य दृष्टिकोण इसे गैर-final छोड़ना पड़ सकता है।

हैं, तो दूसरी ओर, x एक सदस्य चर रहा है, मेरे सलाह आरंभीकरण के दौरान एक गैर final अस्थायी उपयोग करने के लिए होगा:

public class C { 
    private final int x; 
    public C() { 
    int x_val; 
    try { 
     x_val = Integer.parseInt("someinput"); 
    } 
    catch(NumberFormatException e) { 
     x_val = 42; 
    } 
    this.x = x_val; 
    } 
} 
+0

स्थानीय दायरे के लिए मैं आपके साथ सहमत हूं, हालांकि यह अक्सर उदाहरण चर के साथ होता है। – dtech

+0

मुझे लगता है कि यह एक त्रुटि को प्रतिबिंबित कर सकता है गैर-स्थैतिक विधि getValue() के लिए एक स्थिर संदर्भ नहीं बना सकता है, इसलिए हम स्थिर कार्य का उपयोग करने के लिए मानते हैं, मैं गलत निजी स्थिर int getValue() .. @ एनपीई – gks

+0

यदि this.x एक वस्तु-प्रकार है जो इंटीजर की तरह है, तो आपको थोड़ा और (दुख की बात है) की आवश्यकता है। यदि आप x_val अविकसित छोड़ देते हैं, तो संकलक शिकायत करेगा कि इसे प्रारंभ नहीं किया जा सकता है। यदि कैच ब्लॉक के लिए फॉल-बैक शून्य है, तो आपको शून्य से पूर्व-प्रारंभ करने की आवश्यकता है और या तो स्पष्ट रूप से स्पष्टता के लिए पकड़ में शून्य को असाइन करना होगा (यह मेरी वरीयता है) या खाली पकड़ लें। –

2

नहीं यह सही जगह नहीं है, कल्पना करें कि आप मिल गया और अधिक फिर आपके प्रयास और पकड़ ब्लॉक में 1 वक्तव्य, पहला व्यक्ति कहता है: x = 42. कुछ अन्य वक्तव्यों के बाद प्रयास ब्लॉक विफल रहता है, और यह कैच ब्लॉक पर जाता है, जहां आपका कह रहा है x = 30. अब आपने x को दो बार परिभाषित किया है।

+9

कंपाइलर यह समझने के लिए पर्याप्त स्मार्ट है कि कौन से बयान में अपवाद हैं। यह सभी मामलों में संभव नहीं हो सकता है, लेकिन जैसे ही संकलक आपको कुछ मामलों में मृत कोड आदि के बारे में बता सकता है। यह पता लगाने में सक्षम होना चाहिए कि अंतिम काम करेगा या नहीं। – Stefan

+0

@Stefan ने जो समर्थन किया, उसका समर्थन करने के लिए, क्लेंग स्विफ्ट संकलित करते समय इसे समझने में सक्षम है। –