java - जावा: अनचेक अपवाद स्पष्टीकरण बनाम चेक किया गया




exception runtimeexception (14)

  1. क्या उपर्युक्त अपवाद पर विचार किया गया है? नहीं, यह तथ्य कि आप अपवाद को संभालने में सक्षम हैं, यह एक चेक अपवाद नहीं है अगर यह एक रनटाइम अपवाद है।

  2. क्या RuntimeException एक अनचेक अपवाद है? हाँ

चेक किए गए अपवाद java.lang के उप-वर्ग हैं। अपवाद अनचेक अपवाद java.lang के उप-वर्ग हैं। रनटाइम अपवाद

चेक अपवादों को फेंकने वाले कॉलों को {} ब्लॉक या विधि के कॉलर में ऊपर दिए गए स्तर में संभालने की कोशिश में संलग्न होना आवश्यक है। उस स्थिति में वर्तमान विधि को यह घोषणा करनी चाहिए कि यह अपवादों को फेंकता है ताकि कॉलर अपवाद को संभालने के लिए उचित व्यवस्था कर सकें।

उम्मीद है की यह मदद करेगा।

प्रश्न: क्या मुझे अपवाद का उपयोग करके सटीक अपवाद या मुखौटा को बुलबुला करना चाहिए?

ए: हां यह एक बहुत अच्छा सवाल और महत्वपूर्ण डिजाइन विचार है। कक्षा अपवाद एक बहुत ही सामान्य अपवाद वर्ग है और आंतरिक निम्न स्तर के अपवादों को लपेटने के लिए उपयोग किया जा सकता है। आप बेहतर कस्टम अपवाद बनाएंगे और इसके अंदर लपेटेंगे। लेकिन, और एक बड़ा - अंतर्निहित मूल मूल कारण में कभी भी अस्पष्ट नहीं होता है। पूर्व के लिए, Dont ever भी पालन Dont ever करें -

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException("Cannot login!!"); //<-- Eat away original root cause, thus obscuring underlying problem.
}

इसके बजाए निम्नलिखित करें:

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException(sqle); //<-- Wrap original exception to pass on root cause upstairs!.
}

मूल मूल कारण को दूर करना वसूली से परे वास्तविक कारण को जन्म देता है, उत्पादन समर्थन टीमों के लिए एक दुःस्वप्न है जहां उन्हें सभी को एप्लिकेशन लॉग और त्रुटि संदेश तक पहुंच दी जाती है। हालांकि उत्तरार्द्ध एक बेहतर डिजाइन है लेकिन कई लोग अक्सर इसका उपयोग नहीं करते हैं क्योंकि डेवलपर्स कॉलर को अंतर्निहित संदेश को पार करने में असफल होते हैं। तो एक फर्म नोट बनाएं: Always pass on the actual exception किसी भी एप्लिकेशन विशिष्ट अपवाद में लपेटा गया है या नहीं Always pass on the actual exception वापस Always pass on the actual exception

रनटाइचिंग रनटाइम अपवादों पर

एक सामान्य नियम के रूप में रनटाइम अपवादों को कोशिश नहीं किया जाना चाहिए। वे आम तौर पर एक प्रोग्रामिंग त्रुटि संकेत देते हैं और अकेले रहना चाहिए। इसके बजाय प्रोग्रामर को कुछ कोड का आह्वान करने से पहले त्रुटि स्थिति की जांच करनी चाहिए जिसके परिणामस्वरूप रनटाइम अपवाद हो सकता है। पूर्व के लिए:

try {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welome to my site!);
} catch (NullPointerException npe) {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

यह एक खराब प्रोग्रामिंग अभ्यास है। इसके बजाय एक नल-चेक किया जाना चाहिए था -

if (userObject != null) {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welome to my site!);
} else {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

लेकिन ऐसे समय होते हैं जब ऐसी त्रुटि जांच महंगी होती है जैसे संख्या स्वरूपण, इस पर विचार करें -

try {
    String userAge = (String)request.getParameter("age");
    userObject.setAge(Integer.parseInt(strUserAge));
} catch (NumberFormatException npe) {
   sendError("Sorry, Age is supposed to be an Integer. Please try again.");
}

यहां पूर्व-आमंत्रण त्रुटि जांच प्रयास के लायक नहीं है क्योंकि यह अनिवार्य रूप से parseInt () विधि के अंदर सभी स्ट्रिंग-टू-इंटीजर रूपांतरण कोड को डुप्लिकेट करने का मतलब है - और यदि डेवलपर द्वारा लागू किया गया है तो त्रुटि प्रवण है। तो कोशिश करने के साथ बस दूर करना बेहतर है।

तो NullPointerException और NumberFormatException दोनों RuntimeExceptions हैं, एक NullPointerException को पकड़ने के लिए एक सुंदर नल-चेक के साथ प्रतिस्थापित किया जाना चाहिए, जबकि मैं त्रुटि संख्या कोड के संभावित परिचय से बचने के लिए स्पष्ट रूप से संख्या FormatException को पकड़ने की अनुशंसा करता हूं।

मैंने चेक बनाम अनचेक अपवादों के बारे में StackOverFlow पर कई पोस्ट पढ़ी हैं। मैं ईमानदारी से अभी भी सुनिश्चित नहीं हूं कि उन्हें सही तरीके से कैसे उपयोग किया जाए।

" प्रभावी जावा " में जोशुआ ब्लोच ने कहा

प्रोग्रामिंग त्रुटियों के लिए पुनर्प्राप्ति योग्य स्थितियों और रनटाइम अपवादों के लिए चेक अपवादों का उपयोग करें (दूसरे संस्करण में आइटम 58)

चलो देखते हैं कि मैं इसे सही ढंग से समझता हूं या नहीं।

चेक अपवाद की मेरी समझ यहां दी गई है:

try{
    String userInput = //read in user input
    Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
    id = 0; //recover the situation by setting the id to 0
}

1. क्या उपर्युक्त चेक अपवाद पर विचार किया गया है?

2. क्या RuntimeException एक अनचेक अपवाद है?

अनचेक अपवाद की मेरी समझ यहां दी गई है:

try{
    File file = new File("my/file/path");
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){

//3. What should I do here?
    //Should I "throw new FileNotFoundException("File not found");"?
    //Should I log?
    //Or should I System.exit(0);?
}

4. अब, उपर्युक्त कोड भी एक अपवाद अपवाद नहीं हो सकता है? मैं इस तरह की स्थिति को ठीक करने की कोशिश कर सकता हूं? क्या मैं? (नोट: मेरा तीसरा प्रश्न उपरोक्त catch अंदर है)

try{
    String filePath = //read in from user input file path
    File file = new File(filePath);
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){
    //Kindly prompt the user an error message
    //Somehow ask the user to re-enter the file path.
}

5. लोग ऐसा क्यों करते हैं?

public void someMethod throws Exception{

}

वे अपवाद बुलबुला क्यों करते हैं? त्रुटि को जल्दी से बेहतर नहीं कर रहा है? बुलबुला क्यों?

संपादित करें: क्या मुझे अपवाद का उपयोग करके सटीक अपवाद या मुखौटा को बुलबुला करना चाहिए?

नीचे मेरे रीडिंग हैं

जावा में, मुझे एक चेक अपवाद कब बनाना चाहिए, और इसे रनटाइम अपवाद कब होना चाहिए?

चेक और अनचेक अपवादों का चयन कब करें


1) नहीं, एक संख्याफॉर्मेट अपवाद एक अनचेक अपवाद है। भले ही आपने इसे पकड़ा (आपको इसकी आवश्यकता नहीं है) यह अनचेक है। ऐसा इसलिए है क्योंकि यह IllegalArgumentException का उप-वर्ग है जो रनटाइम अपवाद का उप-वर्ग है।

2) रनटाइम अपवाद सभी अनचेक अपवादों की जड़ है। RuntimeException के प्रत्येक उप-वर्ग को अनचेक किया गया है। त्रुटियों को छोड़कर अन्य सभी अपवाद और थ्रोबल्स चेक किए जाते हैं (जो थ्रोबल के अंतर्गत आता है)।

3/4) आप उपयोगकर्ता को सतर्क कर सकते हैं कि उन्होंने एक गैर-मौजूद फाइल चुनी है और एक नया मांगना है। या बस उपयोगकर्ता को सूचित करना छोड़ दें कि उन्होंने कुछ अमान्य दर्ज किया है।

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

कई मामलों में, एक अनचेक अपवाद होता है क्योंकि प्रोग्रामर ने इनपुट सत्यापित नहीं किया है (आपके पहले प्रश्न में NumberFormatException के मामले में)। यही कारण है कि उन्हें पकड़ने के लिए वैकल्पिक, क्योंकि उन अपवादों को उत्पन्न करने से बचने के लिए और अधिक सुरुचिपूर्ण तरीके हैं।


अंतिम प्रश्न का उत्तर देने के लिए (दूसरों को उपरोक्त उत्तर दिया गया है), "क्या मुझे अपवाद का उपयोग करके सटीक अपवाद या मुखौटा बुलबुला करना चाहिए?"

मुझे लगता है कि आप इस तरह कुछ मतलब है:

public void myMethod() throws Exception {
    // ... something that throws FileNotFoundException ...
}

नहीं, हमेशा सबसे सटीक अपवाद संभव है, या इस तरह की एक सूची घोषित करें। अपवाद जो आप फेंकने में सक्षम हैं, आपकी विधि और कॉलर के बीच अनुबंध का हिस्सा हैं। "FileNotFoundException" को फेंकने का अर्थ है कि यह संभव है कि फ़ाइल का नाम मान्य नहीं है और फ़ाइल नहीं मिलेगी; कॉलर को समझदारी से संभालने की आवश्यकता होगी। "अपवाद" को फेंकने का मतलब है "अरे, sh * टी होता है। डील।" जो एक बहुत खराब एपीआई है।

पहले लेख पर टिप्पणियों में कुछ उदाहरण हैं जहां "अपवाद फेंकता है" एक वैध और उचित घोषणा है, लेकिन यह आपके द्वारा कभी भी लिखने वाले "सामान्य" कोड का मामला नहीं है।


चाहे कुछ "चेक अपवाद" है, उसके पास ऐसा करने के लिए कुछ भी नहीं है कि आप इसे पकड़ते हैं या कैच ब्लॉक में क्या करते हैं। यह अपवाद वर्गों की एक संपत्ति है। कुछ भी जो कि RuntimeException और इसके उप-वर्गों को छोड़कर RuntimeException का उप-वर्ग है, एक चेक अपवाद है।

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

वे अपवाद बुलबुला क्यों करते हैं? जल्द से जल्द त्रुटि को संभाल नहीं है? बुलबुला क्यों?

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


जांच की गई - होने के लिए प्रोन। संकलन समय में चेक किया गया।

उदाहरण के लिए .. फाइलऑपरेशन

अनचेक - खराब डेटा के कारण। रन टाइम में चेक किया गया।

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

String s = "abc";
Object o = s;
Integer i = (Integer) o;

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at Sample.main(Sample.java:9)

यहां अपवाद खराब डेटा के कारण है और किसी भी तरह से संकलन समय के दौरान इसे निर्धारित नहीं किया जा सकता है।


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

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

विषय पर मेरा विस्तारित दृश्य यहां दिया गया है

विशेष प्रश्नों के लिए:

  1. क्या NumberFormatException एक्सेप्शन एक चेक अपवाद पर विचार करता है?
    नहीं। NumberFormatException RuntimeException अनचेक किया गया है (= RuntimeException का उप-वर्ग है)। क्यूं कर? मुझे नहीं पता। (लेकिन एक विधि होनी चाहिए isValidInteger(..) )

  2. क्या RuntimeException एक अनचेक अपवाद है?
    हाँ बिल्कुल।

  3. मुझे यहाँ क्या करना चाहिए?
    यह इस कोड पर निर्भर करता है कि आप कहां हैं और आप क्या करना चाहते हैं। यदि यह यूआई परत में है - इसे पकड़ें और चेतावनी दिखाएं; अगर यह सेवा परत में है - इसे बिल्कुल पकड़ न लें - इसे बबल दें। बस अपवाद निगल मत करो। यदि अधिकांश मामलों में कोई अपवाद होता है तो आपको इनमें से कोई एक चुनना चाहिए:

    • इसे लॉग करें और वापस आएं
    • इसे फिर से करें (इसे विधि द्वारा फेंकने की घोषणा करें)
    • कन्स्ट्रक्टर में मौजूदा एक को पास करके एक नया अपवाद बनाएं
  4. अब, उपर्युक्त कोड भी एक अपवाद अपवाद नहीं हो सका? मैं इस तरह की स्थिति को ठीक करने की कोशिश कर सकता हूं? क्या मैं?
    यह हो सकता था। लेकिन कुछ भी आपको अनचेक अपवाद को पकड़ने से रोकता है

  5. लोग फेंकने वाले खंड में कक्षा Exception क्यों जोड़ते हैं?
    अक्सर क्योंकि लोग इस बात पर आलसी हैं कि क्या पकड़ना है और क्या हटाना है। Exception फेंकना एक बुरा अभ्यास है और इससे बचा जाना चाहिए।

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


Checked Exceptions :

  • The exceptions which are checked by the compiler for smooth execution of the program at runtime are called Checked Exception.

  • These occur at compile time.

  • If these are not handled properly, they will give compile time error (Not Exception).
  • All subclasses of Exception class except RuntimeException are Checked Exception.

    Hypothetical Example - Suppose you are leaving your house for the exam, but if you check whether you took your Hall Ticket at home(compile time) then there won't be any problem at Exam Hall(runtime).

Unchecked Exception :

  • The exceptions which are not checked by the compiler are called Unchecked Exceptions.

  • These occur at runtime.

  • If these exceptions are not handled properly, they don't give compile time error. But the program will be terminated prematurely at runtime.

  • All subclasses of RunTimeException and Error are unchecked exceptions.

    Hypothetical Example - Suppose you are in your exam hall but somehow your school had a fire accident (means at runtime) where you can't do anything at that time but precautions can be made before (compile time).


रनटाइम अपवाद रनटाइम अपवादों को अनचेक अपवाद के रूप में जाना जाता है। अन्य सभी अपवादों को अपवादों की जांच की जाती है, और वे java.lang.RuntimeException से प्राप्त नहीं होते हैं।

चेक किए गए अपवाद एक चेक अपवाद को आपके कोड में कहीं भी पकड़ा जाना चाहिए। If you invoke a method that throws a checked exception but you don't catch the checked exception somewhere, your code will not compile. That's why they're called checked exceptions: the compiler checks to make sure that they're handled or declared.

A number of the methods in the Java API throw checked exceptions, so you will often write exception handlers to cope with exceptions generated by methods you didn't write.


All exceptions must be checked exceptions.

  1. Unchecked exceptions are unrestricted gotos. And unrestricted gotos are considered a bad thing.

  2. Unchecked exceptions break encapsulation. To process them correctly, all the functions in the call tree between the thrower and the catcher must be known to avoid bugs.

  3. Exceptions are errors in the function that throws them but not errors in the function that processes them. The purpose of exceptions is to give the program a second chance by deferring the decision of whether it's an error or not to another context. It's only in the other context can the correct decision be made.


All of those are checked exceptions. Unchecked exceptions are subclasses of RuntimeException. The decision is not how to handle them, it's should your code throw them. If you don't want the compiler telling you that you haven't handled an exception then you use an unchecked (subclass of RuntimeException) exception. Those should be saved for situations that you can't recover from, like out of memory errors and the like.



If anybody cares for yet another proof to dislike checked exceptions, see the first few paragraphs of the popular JSON library:

"Although this is a checked exception, it is rarely recoverable. Most callers should simply wrap this exception in an unchecked exception and rethrow: "

So why in the world would anyone make developers keep checking the exception, if we should "simply wrap it" instead? lol

http://developer.android.com/reference/org/json/JSONException.html


Just to point out that if you throw a checked exception in a code and the catch is few levels above, you need to declare the exception in the signature of each method between you and the catch. So, encapsulation is broken because all functions in the path of throw must know about details of that exception.


My absolute favorite description of the difference between unchecked and checked exceptions is provided by the Java Tutorial trail article, " Unchecked Exceptions - the Controversy " (sorry to get all elementary on this post - but, hey, the basics are sometimes the best):

Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception

The heart of "what type of exception to throw" is semantic (to some degree) and the above quote provides and excellent guideline (hence, I am still blown away by the notion that C# got rid of checked exceptions - particularly as Liskov argues for their usefulness).

The rest then becomes logical: to which exceptions does the compiler expect me to respond, explicitly? The ones from which you expect client to recover.





unchecked-exception