2012-11-22 19 views
6

मैंने सी # प्रारंभिक पुस्तक में पढ़ा है कि आपको अपवाद नहीं लेना चाहिए यदि आपको नहीं पता कि इसके साथ क्या करना है। जावा में प्रोग्रामिंग करते समय उस सलाह की सोच के बारे में सोचते हुए, मुझे कभी-कभी पता चलता है कि मुझे नहीं पता कि अपवाद के साथ क्या करना है, लेकिन मुझे संकलन त्रुटि से बचने के लिए इसे पकड़ने के लिए मजबूर होना पड़ता है या इसे "इसे जोड़ना" पड़ता है। मैं throws के साथ क्लटर विधियों को कॉल पेड़ के सभी तरह से क्लॉज नहीं करना चाहता था, इसलिए मैंने अक्सर निम्न में RuntimeException के अपवाद को "रूपांतरित" करने का सहारा लिया है। throws जोड़ना एक अपवाद के लिए कई तरीकों से खंडित है जो वास्तव में "हैंडल" नहीं है (ठीक से निपटाया जाता है) वर्बोज़ और विचलित लगता है। क्या निम्न बुरी शैली है और यदि ऐसा है तो इससे निपटने का एक बेहतर तरीका क्या है?आपदाजनक अपवादों से निपटने

try { 
    thread.join(); 
} 
catch (InterruptedException e) { 
     Console.printwriter.format("%s\n", e.printStackTrace()); 
    throw new RuntimeException(); 
} 

संपादित करें: कोड संशोधन के बाद आप शायद कुछ अनावश्यक throws खंड के साथ अंत: अव्यवस्था के अलावा, वहां percolating अपवादों के साथ एक और समस्या है। उन्हें साफ़ करने का एकमात्र तरीका परीक्षण और त्रुटि से है: उन्हें हटाएं और देखें कि संकलक शिकायत करता है या नहीं। जाहिर है, अगर आप कोड को साफ रखना चाहते हैं तो यह परेशान है।

+0

इससे निपटने का बेहतर तरीका यह है कि कोड को ऐसे तरीके से लिखना है जहां आपको लगातार अपवाद नहीं डालना पड़े। – lifetimes

+0

सहमत हुए। मैं आमतौर पर कई नए परिभाषित अपवादों की घोषणा नहीं करता हूं। मैं मुख्य रूप से तीसरे पक्ष और जावा अपवादों के बारे में चिंतित हूं। – H2ONaCl

+0

@ user1394965 हां, आपका कोड अपवाद "लगातार" नहीं फेंकना चाहिए। लेकिन अपवाद संभव है कि यह एक बहुत ही अलग बात है। आईओ ऑपरेशंस या अवरुद्ध तरीकों से जुड़े कुछ भी अपरिहार्य अपवाद हैंडलिंग के साथ riddled होने की संभावना है। –

उत्तर

5

चेक और अनचेक अपवादों के बीच जावा में विभाजन somewhat controversial है।

यदि आप इंटरफेस को नियंत्रित करते हैं, तो हस्ताक्षर पर फेंकने वाला क्लॉज आमतौर पर सबसे अच्छा तरीका है।

यदि आप ऐसी परिस्थिति में हैं जहां आप अपवाद से निपट नहीं सकते हैं, लेकिन चेक अपवाद हस्ताक्षर के कारण इसे बबल अप करने की अनुमति नहीं है, तो अपवाद को अपवाद में लपेटने के लिए जिसे आप फिर से चला सकते हैं (अक्सर एक रनटाइम अपवाद) सामान्य अभ्यास है।

कई मामलों में, आप एक और चेक अपवाद का उपयोग करना चाहते हैं, हालांकि, IOException या SQLException जैसे। लेकिन यह हमेशा एक विकल्प नहीं है। ,

throw new RuntimeException(e); 

यह भी प्रवेश की आवश्यकता को दूर कर सकते हैं (क्योंकि यह भी कोई है जो अपवाद संभाल कर सकते हैं के लिए स्थगित किया जा सकता है:

लेकिन अपने उदाहरण में, "कारण" के रूप में मूल अपवाद शामिल और सभी जानकारी अभी भी है)।

1

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

+0

@ ब्रॉयन हां, मैं आपके प्रश्न के संदर्भ में जवाब दे रहा था, जहां आप एक सामान्य अपवाद से निपट रहे हैं। – Pablo

1

मुझे जोशुआ ब्लोच के प्रभावी जावा 2 संस्करण में सलाह पसंद है - अमूर्त (आइटम 61) के लिए उपयुक्त अपवाद फेंक दें।

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

इस तरह के दृष्टिकोण में अक्सर एक निम्न उच्च स्तरीय अपवाद में कई निम्न-स्तरीय अपवादों को संयोजित करने का सुखद दुष्प्रभाव होता है।

+0

यह एक अच्छा विचार है। – H2ONaCl

+0

यह आपके कोड बेस को फटकारने वाले सैकड़ों कस्टम अपवादों का आविष्कार करने वाले अपवादों को सरल बनाने के लाभ के बीच एक संतुलित कार्य है। –

1

अच्छी प्रोग्रामिंग प्रथाओं से पता चलता है कि आपको अपने ऑब्जेक्ट्स की आंतरिक स्थिति को इनवोकर्स से छिपाना चाहिए और कम से कम मेरे लिए अपवाद भी शामिल है। आपको देखना चाहिए कि आपके लिए उस अपवाद का क्या अर्थ है और अपनी कक्षा के इनवॉर्टरों को उस अर्थ का प्रतिनिधित्व करने वाले अपवाद पर वापस लौटना चाहिए।

यदि ढांचा पहले से ही उस अर्थ के साथ अपवाद प्रदान करता है, उदाहरण के लिए अवैध अर्ग्यूमेंट एक्सेप्शन, आपको एक नई वस्तु को तत्काल करना चाहिए, इसे एक अच्छा वर्णन के साथ एक स्ट्रिंग दें और ओकुरर्ड अपवाद को समाहित करें, नए अवैध अर्ग्यूमेंट अपवाद के साथ कुछ ("तर्क एक्स के कारण अमान्य है ...", ई); यदि ढांचे में आपकी समस्या के लिए एक अच्छा वर्णनात्मक अपवाद नहीं है, तो आपको अपवादों का अपना सेट बनाना चाहिए। मैं आम तौर पर उस परियोजना/पैकेज (जो अपवाद या रनटाइम अपवाद का विस्तार करेगा) के लिए एक सामान्य अपवाद बनाते हैं और उससे अपवाद व्युत्पन्न करते हैं। उदाहरण के लिए, मैंने हाल ही में डेटाबेस तक पहुंचने के लिए हमारी सेवाओं और अनुप्रयोग मॉड्यूल में पुन: उपयोग करने के लिए एक जेनेरिक रिपोजिटरी प्रोजेक्ट बनाया है। चूंकि मैं अपवादों से भी डीबी तक पहुंचने के लिए उपयोग कर रहा था, उससे आवेदकों को अमूर्त करना चाहता था, इसलिए मैंने जेपीए हाइबरनेट अपवादों को समाहित करने के लिए कुछ अपवाद तैयार किए। मेरे पास कोड नहीं है, लेकिन यह कुछ ऐसा था:

// implementation package 
public abstract class GenericRepository<K, E extends<K>> implements IRepository<K, E>{ 

    // constructors 

    public final void add(E entity){ 
     // some code 

     try{ 
      // code that can throw exceptions 
     } catch (EntityExistsException e) { 
      // some code 
      throw new EntityAlreadyExistsException(e); 
     } catch(RuntimeException e) { 
      // some code 
      throw new GenericRepositoryException("An unexpected exception occurred while manipulating the database", e); 
     } 
    } 

    // some other code 

} 


// exception package 
public final class EntityAlreadyExistsException extends GenericRepositoryException{ 

    public static final String GENERICMESSAGE = "The entity already exists on the table"; 

    public EntityAlreadyExistsException(Throwable cause){ 
     super(GENERICMESSAGE, cause); 
    } 

    // other constructors 

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