अपवाद का उपयोग कब करना है और अपवाद का उपयोग कब करना है


121

अधिकांश समय मैं अपने कोड में एक स्थिति की जांच करने के लिए एक अपवाद का उपयोग करूंगा, मुझे आश्चर्य है कि जब यह दावा करने के लिए उपयुक्त समय है?

उदाहरण के लिए,

Group group=null;
try{
    group = service().getGroup("abc");
}catch(Exception e){
    //I dont log error because I know whenever error occur mean group not found
}

if(group !=null)
{
    //do something
}

क्या आप इंगित कर सकते हैं कि कैसे एक जोर यहाँ फिट बैठता है? क्या मुझे दावा करना चाहिए?

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

जवाबों:


81

कथनों का उपयोग किसी ऐसी चीज़ की जाँच करने के लिए किया जाना चाहिए जो कभी नहीं होनी चाहिए, जबकि एक अपवाद का उपयोग कुछ ऐसा करने के लिए किया जाना चाहिए जो हो सकता है।

उदाहरण के लिए, एक फ़ंक्शन 0 से विभाजित हो सकता है, इसलिए एक अपवाद का उपयोग किया जाना चाहिए, लेकिन यह जांचने के लिए इस्तेमाल किया जा सकता है कि हार्डड्राइव अचानक गायब हो जाता है।

एक जोर से चलने से कार्यक्रम बंद हो जाएगा, लेकिन एक अपवाद कार्यक्रम को जारी रखने देगा।

ध्यान दें कि if(group != null)एक जोर नहीं है, यह सिर्फ एक सशर्त है।


3
"यह दावा करने के लिए इस्तेमाल किया जा सकता है कि हार्डड्राइव अचानक गायब हो जाता है" - मैं कहूंगा कि यह सही नहीं है: आप यह विकास के दौरान क्यों संभालना चाहते हैं, लेकिन उत्पादन में नहीं (जब दावे आम तौर पर अक्षम होते हैं)?
हरमन

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

1
@ मेरी आपकी स्थिति को इस तरह से बदल दिया जा सकता है:
मुखर

1
नीचा दिखाया गया है क्योंकि हार्ड ड्राइव उदाहरण आपके स्वयं के दर्शन का खंडन करता है। हार्ड ड्राइव "गायब" (कोड के दृष्टिकोण से) वास्तव में वास्तविकता में हो सकता है - कोई फर्क नहीं पड़ता कि कितना असंभव है। जैसे @IanGoldby कहती है, मुखरता आपके कोड द्वारा नियंत्रित चीजों पर पूरी तरह निर्भर होनी चाहिए।
विक्की चिजवानी

ग्रेगरी पॉक्सोज़ द्वारा पोस्ट किए जाने पर एक बेहतर उत्तर, कृपया उस पोस्ट को पढ़ें।
ormurin

169

मेरे दिमाग से (सूची अधूरी हो सकती है, और एक टिप्पणी में फिट होने के लिए बहुत लंबा है), मैं कहूंगा:

  • सार्वजनिक या संरक्षित विधियों और निर्माणकर्ताओं को दिए गए मापदंडों की जाँच करते समय अपवादों का उपयोग करें
  • उपयोगकर्ता के साथ बातचीत करते समय या जब आप क्लाइंट कोड से असाधारण स्थिति से उबरने की अपेक्षा करते हैं तो अपवादों का उपयोग करें
  • समस्याओं का समाधान करने के लिए अपवादों का उपयोग करें
  • निजी / आंतरिक कोड की पूर्व-स्थितियों, पोस्ट-स्थितियों और अपरिवर्तनों की जांच करते समय मुखरता का उपयोग करें
  • अपने या अपने डेवलपर टीम को प्रतिक्रिया प्रदान करने के लिए अभिकथन का उपयोग करें
  • उन चीज़ों की जाँच करते समय उपयोग करें जो बहुत अधिक होने की संभावना नहीं है अन्यथा इसका मतलब है कि आपके आवेदन में एक गंभीर in जाग है
  • उन चीज़ों को बताने के लिए जो आपको (माना जाता है) सही होने के लिए उपयोग करें

दूसरे शब्दों में, अपवाद आपके आवेदन की मजबूती को संबोधित करते हैं जबकि दावे इसकी शुद्धता को संबोधित करते हैं।

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


53
मुझे यह पसंद है कि जिस तरह से आपने इसे बनाया है: अपवाद आपके आवेदन की मजबूती को संबोधित करते हैं जबकि दावे इसकी शुद्धता को संबोधित करते हैं
एम। डडले

मैंने इसे अपनी साइट पर पोस्ट कर दिया है: pempek.net/articles/2013/11/16/assertions-or-exception
ग्रेगरी पकोस्ज़

और अगर आप C ++ कस्टम
एस्टर

26

याद रखें कि मापदंडों का उपयोग करके रनटाइम पर अक्षम किया जा सकता है, और डिफ़ॉल्ट रूप से अक्षम किया जाता है , इसलिए डिबगिंग उद्देश्यों को छोड़कर उन पर भरोसा न करें।

इसके अलावा, आपको अधिक मामलों को देखने के लिए assert के बारे में Oracle लेख पढ़ना चाहिए जहां - उपयोग करने के लिए - या उपयोग नहीं करना है।


Hue hue hue hue मैं सोच रहा था कि मेरा कोड एक्लिप्स में क्यों फेल हो रहा था लेकिन कमांड लाइन पर ठीक चल रहा था।
स्टीव

15

एक सामान्य नियम के रूप में:

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

आपके प्रश्न का निम्नलिखित कोड खराब शैली और संभावित रूप से छोटी गाड़ी है

try {
    group = service().getGroup("abc");
} catch (Exception e) {
    //i dont log error because i know whenever error occur mean group not found
}

समस्या यह है कि आपको पता नहीं है कि अपवाद का मतलब है कि समूह नहीं मिला। यह भी संभव है कि service()कॉल ने एक अपवाद को फेंक दिया, या यह कि वह वापस आ गया nullजिसके कारण ए NullPointerException

जब आप "अपेक्षित" अपवाद को पकड़ते हैं, तो आपको केवल उस अपवाद को पकड़ना चाहिए जिसकी आप अपेक्षा कर रहे हैं। पकड़कर java.lang.Exception(और विशेष रूप से इसे लॉग इन न करके), आप समस्या का निदान / डीबग करना कठिन बना रहे हैं, और संभवतः एप्लिकेशन को अधिक नुकसान करने की अनुमति देते हैं।


4

ठीक है, Microsoft पर, अनुशंसा यह थी कि सभी API में अपवादों को आप सार्वजनिक रूप से उपलब्ध कराएं और Asserts का उपयोग उन सभी प्रकार की मान्यताओं में करें, जो आप आंतरिक हैं। यह थोड़ी ढीली परिभाषा है, लेकिन मुझे लगता है कि यह रेखा खींचने के लिए प्रत्येक डेवलपर पर निर्भर है।

अपवादों के उपयोग के बारे में, जैसा कि नाम कहता है, उनका उपयोग असाधारण होना चाहिए ताकि आपके ऊपर मौजूद कोड के लिए, कोई सेवा मौजूद न होने getGroupपर कॉल वापस आ nullजाए। अपवाद केवल तभी होना चाहिए जब कोई नेटवर्क लिंक नीचे जाए या ऐसा कुछ हो।

मुझे लगता है कि निष्कर्ष यह है कि प्रत्येक आवेदन के लिए विकास टीम के लिए थोड़ा सा नीचे छोड़ दिया गया है ताकि वे जोरदार अपवादों की सीमाओं को परिभाषित कर सकें।


IMHO, इस तरह की सिफारिश के साथ समस्या यह है कि यह तब तक ठीक है जब तक कि एपीआई के सार्वजनिक और निजी भागों के बीच की सीमा बहुत तय नहीं हो जाती। यदि आप नया कोड विकसित कर रहे हैं, तो यह सीमा अक्सर बहुत तरल होती है ...
लेन होलगेट

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

3

इस दस्तावेज़ के अनुसार http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general , "मुखर कथन अप्रतिबंधित पूर्व शर्त, पोस्टकॉन्डिशन और क्लास इनवेरिएंट के लिए उपयुक्त है जाँच। सार्वजनिक पूर्वधारणा जाँच अभी भी उन विधियों के अंदर जाँच के द्वारा की जानी चाहिए जो विशेष रूप से परिणामित हों, जैसे कि अपवाद, अवैध अपवाद जैसे कि IllegalArgumentException और IllegalStateException। "

यदि आप पूर्वनिर्धारण, पोस्टकंडिशन और क्लास इनवेरिएंट के बारे में अधिक जानना चाहते हैं, तो इस डॉक्टर की जाँच करें: http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html/usage-conditions । इसमें मुखर उपयोग के उदाहरण भी शामिल हैं।


1

नल के लिए परीक्षण केवल समस्या पैदा करने वाले नल को पकड़ लेगा, जबकि एक कोशिश / पकड़ के रूप में आप इसे किसी भी पकड़ लेंगे त्रुटि ।

मोटे तौर पर, कोशिश / पकड़ सुरक्षित है, लेकिन थोड़ा धीमा है, और आपको सावधान रहना होगा कि आप सभी प्रकार की त्रुटि पकड़ सकते हैं जो हो सकती है। तो मैं कहूंगा कि कोशिश / पकड़ का उपयोग करें - एक दिन गेटग्रुप कोड बदल सकता है, और आपको बस उस बड़े जाल की आवश्यकता हो सकती है।


1

आप इस सरल अंतर को उनके उपयोग के समय ध्यान में रख सकते हैं। अपवादों को अपेक्षित और अप्रत्याशित त्रुटियों की जाँच के लिए उपयोग किया जाएगा, जिन्हें चेक और अनियंत्रित त्रुटि कहा जाता है, जबकि मान्यता का उपयोग मुख्य रूप से रनिंग समय पर डिबगिंग उद्देश्यों के लिए किया जाता है, ताकि यह देखा जा सके कि मान्यताओं को मान्य किया गया है या नहीं।


1

मैं स्वीकार करता हूं कि मैं आपके प्रश्न से थोड़ा भ्रमित हूं। जब एक जोरदार शर्त पूरी नहीं होती है, तो एक अपवाद फेंक दिया जाता है। भ्रामक रूप से इसे AssertionError कहा जाता है । ध्यान दें कि यह अनियंत्रित है, जैसे (उदाहरण के लिए) IllegalArgumentException जिसे बहुत समान परिस्थितियों में फेंका गया है।

तो जावा में जोर का उपयोग कर

  1. एक शर्त / फेंक ब्लॉक लिखने का एक और अधिक संक्षिप्त साधन है
  2. JVM मापदंडों के माध्यम से आपको इन चेक को चालू / बंद करने की अनुमति देता है। आम तौर पर मैं इन जांचों को हर समय छोड़ देता हूं, जब तक कि वे रनटाइम प्रदर्शन को प्रभावित नहीं करते हैं या समान दंड नहीं देते हैं।

जोर-जबरदस्ती त्रुटि का एक उपवर्ग है जो RuntimeException नहीं है।
स्टीफन C

आह। बेशक। मैं जाँच / अनियंत्रित के बारे में सोच रहा था। अब सही किया गया
ब्रायन एग्न्यू

यह बताता है कि दावे क्या हैं (विवादास्पद दृष्टिकोण से), लेकिन नहीं जब उन्हें बिल्कुल उपयोग करने के लिए।
कार्ल रिक्टर

1

निम्नलिखित लिंक पर सूर्य के प्रलेखन का खंड 6.1.2 (अन्य बनाम कोड त्रुटि) देखें।

http://www.oracle.com/technetwork/articles/javase/javapch06.pdf

यह दस्तावेज़ सबसे अच्छी सलाह देता है जो मैंने देखा है कि कब उपयोग करना है। दस्तावेज़ से उद्धरण:

"अंगूठे का एक अच्छा नियम यह है कि आपको असाधारण मामलों के लिए एक मुखरता का उपयोग करना चाहिए, जिसके बारे में आप भूलना चाहते हैं। एक मुखर व्यवहार से निपटने के लिए सबसे तेज़ तरीका है, और भूल जाते हैं, एक ऐसी स्थिति या स्थिति जिसके बारे में आपको उम्मीद नहीं है। से निपटें।"


0

दुर्भाग्य से जोर दिया जा सकता है। जब उत्पादन में आपको किसी अप्रत्याशित चीज़ को ट्रैक करते समय मिल सकने वाली सभी मदद की ज़रूरत होती है, तो यह दावा खुद को अयोग्य घोषित कर देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.