2012-12-23 16 views
15

मुझे जावा में checked और unchecked अपवादों के बीच अंतर को समझने में कुछ समस्याएं आ रही हैं।जावा में चेक किए गए बनाम अनचेक अपवाद

  1. सबसे पहले, checked अपवादों को संकलन समय के दौरान असामान्यताओं की तलाश करनी चाहिए। विभिन्न स्रोतों में दिए गए उदाहरणों, डेटाबेस कनेक्टिविटी, उनमें से कुछ के रूप में फ़ाइल से निपटने का हवाला देते हैं, जबकि unchecked अपवाद हैं, एक सरणी की सीमा से परे अनुक्रमण तरह प्रोग्रामर की ओर से त्रुटियों के लिए देखने के लिए अपेक्षा की जाती है, आदि

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

2 दूसरे, कैसे RunTimeException, जो अपने आप unchecked, किया जा रहा है कर सकते हैं उपवर्ग Exception, जो checked है? यह क्या संकेत करता है?

class ThrowsDemo { 
    public static char prompt(String str) 
     throws java.io.IOException { 
    System.out.print(str + ": "); 
    return (char) System.in.read(); 
    } 
    public static void main(String args[]) { 
    char ch; 
    try { 
     ch = prompt("Enter a letter"); 
    } 
    catch(java.io.IOException exc) { 
    System.out.println("I/O exception occurred."); 
    ch = 'X'; 
    } 
    System.out.println("You pressed " + ch); 
    } 
} 

यहाँ throws खंड आवश्यक है:

मैं checked अपवाद के उपयोग समझा हरबर्ट शिल्डट की किताब में एक उदाहरण पाया? मैं क्यों यह सिर्फ सामान्य रूप से ऐसा नहीं कर सकते एक try-catch बयान इस तरह के साथ (खेद मैं नहीं पता है एक IO Exception अनुकरण करने के लिए कैसे, तो यह अपने आप की जाँच नहीं कर सका!):

class ThrowsDemo { 
    public static char prompt(String str) { 
    System.out.print(str + ": "); 
    return (char) System.in.read(); 
    } 
    public static void main(String args[]) { 
    char ch; 
    try { 
     ch = prompt("Enter a letter"); 
    } 
    catch(java.io.IOException exc) { 
    System.out.println("I/O exception occurred."); 
    ch = 'X'; 
    } 
    System.out.println("You pressed " + ch); 
    } 
} 
+0

[अनियंत्रित अपवाद या क्रम अपवाद के बीच अंतर] की संभावित डुप्लिकेट (http://stackoverflow.com/questions/2699580/difference-between-unchecked-exception-or-runtime-exception) – Tom

+0

चेक किए गए अपवाद हैं संकलन-समय की समस्याओं का पता लगाने के लिए नहीं *। यह संकलक त्रुटियों का उद्देश्य है। – erickson

उत्तर

21

CheckedException फोन करने वाले द्वारा नियंत्रित किया जा करने की जरूरत है, अनियंत्रित अपवाद नहीं है।

इसलिए, जब आप अपने आवेदन डिजाइन को ध्यान में रखना चाहिए असाधारण स्थिति आप किस तरह का प्रबंधन कर रहे हैं।

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

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

इसके बजाए, ऐसी कई स्थितियां हैं जो नहीं होनी चाहिए, और/या इसके बजाय कार्यक्रम को तोड़ना चाहिए। उदाहरण के लिए, (शून्य से भाग, नल पॉइंटर एक्सेप्शन) की तरह एक प्रोग्रामिंग त्रुटि, एक API के गलत उपयोग (IllegalStateException, OperationNotSupportedException), एक हार्डवेयर दुर्घटना, या बस कुछ मामूली स्थिति है कि वसूली (एक सर्वर से कनेक्शन खो) नहीं हैं, या एक डूम्सडे :-); उन मामलों में, सामान्य हैंडलिंग अपवाद को आपके कोड के सबसे बाहरी ब्लॉक तक पहुंचने देना है जो उपयोगकर्ता को प्रदर्शित करता है कि एक अप्रत्याशित त्रुटि आई है और एप्लिकेशन जारी रखने के लिए कुछ भी नहीं कर सकता है। यह एक घातक स्थिति है, इसलिए केवल एक चीज जो आप कर सकते हैं उसे लॉग में प्रिंट करना या उपयोगकर्ता इंटरफ़ेस में उपयोगकर्ता को दिखाना है। उन मामलों में, अपवाद को पकड़ना गलत है, क्योंकि, अपवाद को पकड़ने के बाद आपको अधिक नुकसान से बचने के लिए प्रोग्राम को मैन्युअल रूप से रोकना होगा; तो यह अपवाद किसी तरह :)

उन कारणों के लिए "प्रशंसक हिट" कुछ अपवाद है कि JRE में भी अनियंत्रित रहे हैं जाने के लिए बेहतर हो सकता है: OutOfMemoryError (अप्राप्य), NullPointerException (यह एक बग है कि करने की जरूरत है तय किया जाना चाहिए), ArrayIndexOutOfBoundsException (एक और बग उदाहरण), और इसी तरह।

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

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

+0

कूल। बस कुछ प्रश्न, यदि कोई अप्राप्य त्रुटि है, तो JVM इसे वैसे भी समाप्त कर देगा। तो रन-टाइम अपवाद बढ़ाने का क्या मतलब है? केवल उचित स्थिति संदेश देने के लिए? मैं इस धारणा के तहत था कि अपवाद आपको त्रुटि को फंसाने देते हैं, कुछ ब्रश-अप काम करते हैं और कार्यक्रम को सामान्य रूप से फिर से शुरू करते हैं।और दूसरी बात, आप चेक अपवाद से कैसे 'पुनर्प्राप्त' कर सकते हैं? 'पुनर्प्राप्ति' से आपका क्या मतलब है? – SexyBeast

+2

वास्तव में नहीं। यदि फाइल सिस्टम पर कोई क्रैश है, तो आपका JVM अभी भी चल सकता है। मुझे लगता है कि अगर आउटऑफ मेमरी एरर भी है, तो जेवीएम रुकता नहीं है: ऐसे थ्रेड हैं जिन्हें अतिरिक्त मेमोरी की आवश्यकता नहीं है ताकि वे जारी रख सकें, या कुछ संदर्भ बाद में मुक्त हो सकते हैं और प्रोग्राम अभी भी ठीक से काम कर सकता है। एक रनटाइम अपवाद को उठाना मतलब है "यह अपवाद, आमतौर पर आप नहीं/नहीं कर सकते हैं, लेकिन यदि आप चाहते हैं, तो स्वतंत्र महसूस करें"। उदाहरण के लिए, यदि मैंने एक विशेष कंप्यूटर डिज़ाइन किया है जो मशीनों में नए रैम चिप्स को माउंट करने में सक्षम है, तो मैं OutOfMemoryException को भी संभाल सकता हूं! :) –

+0

'पुनर्प्राप्ति' से मेरा मतलब इस तरह का परिदृश्य है: आप एक विधि को कॉल करते हैं जो एक सॉकेट के माध्यम से रिमोट कंप्यूटर पर कुछ संदेश भेजता है। अगर कनेक्शन अस्थायी रूप से गिरता है, तो मैं हारने से पहले दो बार फिर कोशिश कर रहा हूं। यह तय करना आपकी पसंद है कि उपयोगकर्ता को मैन्युअल रूप से पुनः प्रयास करने या अपने सॉफ़्टवेयर में इस 'पुनर्प्राप्ति' तर्क को लागू करने के लिए सबसे अच्छा है या नहीं। यदि आप ऐसे उपयोगकर्ता से बात कर रहे हैं जो मैन्युअल रूप से 'पुनर्प्राप्त नहीं' नीति को पुनः प्रयास कर सकता है तो शायद सबसे अच्छा है। लेकिन यदि आप उपयोगकर्ता इंटरैक्शन के बिना चल रहे सर्वर को कार्यान्वित कर रहे हैं, तो आपको सोचना चाहिए कि क्या अस्थायी नेटवर्क विफलताओं को पुनर्प्राप्त करने का मामला –

8
  1. तुम नहीं throws खंड में अनचेक अपवादों की घोषणा करने की आवश्यकता है; लेकिन आप चेक अपवाद घोषित करना चाहिए;
  2. RuntimeException और Error, और उनके सभी उप-वर्ग (IllegalArgumentException, StackOverflowError आदि), अनजान अपवाद हैं; तथ्य यह है कि RuntimeException अनचेक है, अन्य Throwable सबक्लास के विपरीत, डिज़ाइन द्वारा है;
  3. "संकलन समय अपवाद" जैसी कोई चीज़ नहीं है।

अधिक आम तौर पर, ऐसा माना जाता है कि या तो JVM त्रुटियों या प्रोग्रामर त्रुटियों की स्थिति में अनचेक अपवाद फेंक दिए जाते हैं। एक प्रसिद्ध ऐसा अपवाद NullPointerException है, जिसे अक्सर एनपीई के रूप में संक्षिप्त किया जाता है, जो RuntimeException का उप-वर्ग है, और इसलिए अनचेक किया जाता है।

अनचेक अपवादों और चेक अपवादों के बीच एक और महत्वपूर्ण अंतर यह है कि यदि आप अनचेक अपवादों को पकड़ना चाहते हैं, तो आपको उन्हें स्पष्ट रूप से पकड़ना होगा।

अंतिम नोट: यदि आप अपवाद वर्ग E1 और E2 और E2E1 फैली हुई है, तो पकड़ने और/या E1 फेंकने भी फैल जाती है/फेंकता E2। यह चेक और अनचेक अपवाद दोनों के लिए खड़ा है।catch ब्लॉक पर इसका निहितार्थ है: यदि आप E2 और E1 को पकड़ने के बीच अंतर करते हैं, तो आप E2 को पहले पकड़ लेंगे।

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

// IllegalArgumentException is unchecked, no need to declare it 
public void illegal() 
{ 
    throw new IllegalArgumentException("meh"); 
} 

// IOException is a checked exception, it must be declared 
public void ioerror() 
    throws IOException 
{ 
    throw new IOException("meh"); 
} 

// Sample code using illegal(): if you want to catch IllegalArgumentException, 
// you must do so explicitly. Not catching it is not considered an error 
public void f() 
{ 
    try { 
     illegal(); 
    } catch (IllegalArgumentException e) { // Explicit catch! 
     doSomething(); 
    } 
} 

मुझे आशा है कि यह बातें स्पष्ट करता है ...

2

संकलक केवल बनाता है यकीन है कि अगर यह यह घोषणा नहीं की थी एक विधि एक जाँच अपवाद नहीं फेंक सकते हैं। यह एक सामान्य धारणा है कि संकलक द्वारा ऐसी जांच उन अपवादों के लिए की जानी चाहिए जिनकी घटना प्रोग्रामर के नियंत्रण से बाहर है, जैसे कि आपके द्वारा उद्धृत उदाहरण (डेटाबेस कनेक्टिविटी, फाइल गायब, इत्यादि)। अनचेक अपवाद "होने वाला नहीं है", इसलिए संकलक आपको घोषित करने के लिए मजबूर नहीं करता है।

IOException या किसी अन्य का अनुकरण के लिए, यह मामूली बात है:

throw new IOException(); 

अपने उदाहरण में prompt विधि एक IOException फेंक सकता है, यही कारण है कि यह यह घोषणा करने की जरूरत है। उस बिंदु पर अपवाद को संभालने के तरीके के साथ इसका कोई लेना-देना नहीं है जिसे आप विधि कहते हैं।

RuntimeExceptionException का एक उपवर्ग यह सुविधाजनक एक catch Exception खंड के साथ सभी अपवादों को पकड़ने के लिए करना है। यह अलग-अलग डिजाइन किया जा सकता था; जावा का अपवाद वर्ग पदानुक्रम एक गड़बड़ है।

+0

फ़ाइल-हैंडलिंग या डेटाबेस कनेक्टिंग रन-टाइम पर की जाती है, संकलन-समय के दौरान उन्हें कैसे चेक किया जा सकता है? – SexyBeast

+0

कंपाइलर केवल यह सुनिश्चित करता है कि कोई विधि चेक अपवाद नहीं फेंक दे, अगर उसने इसे घोषित नहीं किया है। –

0

डाल न तो यहाँ में खंड फेंकता है तो यह त्रुटि हो जाएगा

ThrowsDemo.java:5: असूचित अपवाद java.io.IOException; पकड़ा जाना चाहिए या घ फेंक दिया करने के लिए वापसी (चार) eclared System.in.read();

इसलिए आवश्यक में खंड फेंकता है।

5
  1. नहीं। सभी अपवाद रनटाइम पर होते हैं। चेक किए गए अपवाद अपवाद हैं जो कॉलर को उन्हें संभालने या उन्हें घोषित करने के लिए मजबूर करते हैं। वे आम तौर पर पुनर्प्राप्ति योग्य त्रुटियों को सिग्नल करने के लिए लक्षित होते हैं, जो प्रोग्रामर त्रुटि (जैसे फ़ाइल नहीं है, या नेटवर्क कनेक्टिविटी समस्या) के कारण नहीं होते हैं। रनटाइम अपवाद आमतौर पर गैर पुनर्प्राप्ति योग्य त्रुटियों को सिग्नल करने का इरादा रखते हैं। वे कॉलर को संभालने या घोषित करने के लिए मजबूर नहीं करते हैं। और उनमें से कई वास्तव में प्रोग्रामिंग त्रुटियों को सिग्नल करते हैं (जैसे NullPointerException)।

  2. इसीलिए जेएलएस एक अनचेक अपवाद को परिभाषित करता है: एक अपवाद जो रनटाइम अपवाद है या विस्तार करता है, जो स्वयं अपवाद को बढ़ाता है। एक विरासत रूट का उपयोग करना एक ही पकड़ खंड में हर संभव अपवाद को संभालने की अनुमति देता है।

अपने उदाहरण के बारे में: हाँ, फेंकता खंड, अनिवार्य है के बाद से IOException एक जाँच अपवाद नहीं है और कहा कि विधि के अंदर कोड अतिसंवेदनशील है एक फेंकने के लिए।

+0

मुझे समझ में नहीं आता है, आप संकलन समय के दौरान फ़ाइल-हैंडल की वैधता की जांच कैसे कर सकते हैं? और मैं इसे सामान्य 'प्रयास-पकड़' कथन के साथ क्यों नहीं कर सकता? यहां 'फेंकता' क्या हासिल करता है जो 'कोशिश-पकड़' नहीं कर सकता है? – SexyBeast

+1

सभी अपवाद रनटाइम पर होते हैं। यह मेरे जवाब का पहला शब्द है। कोई संकलन-समय अपवाद नहीं है। वह अस्तित्व में नहीं है। 'थ्रो' सिग्नल जो एक विधि को अपवाद फेंक सकता है जब इसे बुलाया जाता है। 'कोशिश/पकड़' एक बुलाया विधि द्वारा फेंक दिया अपवाद पकड़ता है। 'फेंकता' एक "खतरे! फिसलन जमीन" पैनल की तरह है। 'कोशिश/पकड़' की तरह है "वाह, जमीन फिसलन है। मैं इसका ख्याल रखूंगा"। –

+0

तो मैं हमेशा 'फेंकने' के स्थान पर 'कोशिश-पकड़' का उपयोग क्यों नहीं कर सकता? – SexyBeast

0

की जाँच की और अनियंत्रित अपवाद

कुछ अपवाद भी दो प्रकार के होते हैं: अपवाद और अनियंत्रित अपवाद जाँच की। की जाँच की और अनियंत्रित अपवाद के बीच मुख्य अंतर यह है कि जांचे हुए अपवादों संकलन समय पर जाँच कर रहे हैं, जबकि अनियंत्रित अपवाद रनटाइम पर जाँच कर रहे हैं है।

कृपया स्पष्ट विचार प्राप्त करने के लिए यह article पढ़ें।

0

More Details

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

1

चेक अपवाद और अनचेक अपवाद का पांच उदाहरण।

Unchecked Exception 
    -- NullPointerException 
    -- ArrayIndexOutofBound 
    -- IllegalArgument Exception 
    -- ClassCastException 
    -- IllegalStateException 
    -- ConcurrentModificationException 

Checked Exception Five Example 
    -- FileNotFoundException 
    -- ParseException 
    -- ClassNotFoundException 
    -- CloneNotSupportException 
    -- SQLException 
*
संबंधित मुद्दे