जवाबों:
आम तौर पर, कभी नहीं।
हालांकि, कभी-कभी आपको विशिष्ट त्रुटियों को पकड़ने की आवश्यकता होती है।
यदि आप फ्रेमवर्क-ईश कोड (तृतीय पक्ष कक्षाएं लोड कर रहे हैं) लिख रहे हैं, तो इसे पकड़ना बुद्धिमान हो सकता है LinkageError
(कोई वर्ग दोष नहीं पाया गया, असंतुष्ट लिंक, असंगत वर्ग परिवर्तन)।
मैंने कुछ बेवकूफ 3-पार्टी कोड को उपवर्गों को फेंकते हुए भी देखा है Error
, इसलिए आपको उन्हें भी संभालना होगा।
वैसे, मुझे यकीन नहीं है कि इससे उबरना संभव नहीं है OutOfMemoryError
।
कभी नहीँ। आप कभी भी यह सुनिश्चित नहीं कर सकते हैं कि एप्लिकेशन कोड की अगली पंक्ति को निष्पादित करने में सक्षम है। यदि आप एक प्राप्त करते हैं OutOfMemoryError
, तो आपके पास कोई गारंटी नहीं है कि आप मज़बूती से कुछ भी करने में सक्षम होंगे । RuntimeException को पकड़ो और अपवाद की जाँच की, लेकिन त्रुटियां कभी नहीं।
boolean assertionsEnabled = false; assert assertionsEnabled = true;
आम तौर पर आपको हमेशा java.lang.Error
लॉग को पकड़ना चाहिए और उसे लिखना चाहिए या उसे उपयोगकर्ता को दिखाना चाहिए। मैं समर्थन में काम करता हूं और दैनिक देखता हूं कि प्रोग्रामर यह नहीं बता सकते कि एक कार्यक्रम में क्या हुआ है।
यदि आपके पास डेमन धागा है तो आपको इसे समाप्त होने से रोकना चाहिए। अन्य मामलों में आपका आवेदन सही ढंग से काम करेगा।
आपको केवल java.lang.Error
उच्चतम स्तर पर पकड़ चाहिए ।
यदि आप त्रुटियों की सूची को देखते हैं तो आप देखेंगे कि अधिकांश को संभाला जा सकता है। उदाहरण के लिए ZipError
भ्रष्ट ज़िप फ़ाइलों को पढ़ने पर होता है।
सबसे आम त्रुटियां हैं OutOfMemoryError
और NoClassDefFoundError
, जो कि ज्यादातर मामलों में रनटाइम की समस्याएं हैं।
उदाहरण के लिए:
int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];
उत्पादन कर सकता है, OutOfMemoryError
लेकिन यह एक रनटाइम समस्या है और आपके कार्यक्रम को समाप्त करने का कोई कारण नहीं है।
NoClassDefFoundError
ज्यादातर तब होता है जब एक पुस्तकालय मौजूद नहीं होता है या यदि आप किसी अन्य जावा संस्करण के साथ काम करते हैं। यदि यह आपके कार्यक्रम का एक वैकल्पिक हिस्सा है तो आपको अपना कार्यक्रम समाप्त नहीं करना चाहिए।
मैं कई और उदाहरण दे सकता हूं Throwable
कि शीर्ष स्तर पर पकड़ना और एक उपयोगी त्रुटि संदेश उत्पन्न करना एक अच्छा विचार क्यों है ।
OutOfMemoryError
कोई रनटाइम त्रुटि नहीं है कोई गारंटी नहीं है कि एप्लिकेशन इससे पुनर्प्राप्त कर सकता है। यदि आप भाग्यशाली हैं, तो आपको OOM मिल सकता है, new byte[largeNumber]
लेकिन यदि वह आवंटन OOM का कारण बनने के लिए पर्याप्त नहीं था, तो इसे अगली पंक्ति या अगले थ्रेड में ट्रिगर किया जा सकता है। यह रनटाइम समस्या है क्योंकि यदि length
अविश्वासित इनपुट है तो इसे कॉल करने से पहले मान्य किया जाना चाहिए new byte[]
।
NoClassDefFoundError
कहीं भी हो सकता है , क्योंकि यह संकलित है जब संकलित जावा कोड एक वर्ग नहीं पा सकता है। यदि आपका JDK गलत है तो वह java.util.*
वर्ग का उपयोग करने की कोशिश कर सकता है और इसके खिलाफ प्रोग्राम करना व्यावहारिक रूप से असंभव है। यदि आप वैकल्पिक रूप से एक निर्भरता सहित हैं, तो आपको ClassLoader
यह जांचने के लिए उपयोग करना चाहिए कि क्या यह मौजूद है, जो फेंकता है ClassNotFoundException
।
ZipError
इंगित करता है कि jar फ़ाइल जिसमें कक्षाएं हैं एक दूषित ज़िप फ़ाइल है। यह काफी गंभीर मुद्दा है और इस बिंदु पर आप किसी भी कोड पर विश्वास नहीं कर सकते हैं जो निष्पादित हो जाता है और इससे "पुनर्प्राप्त" करने के प्रयास के लिए यह गैर जिम्मेदाराना होगा।
java.lang.Error
या java.lang.Throwable
इसके साथ कुछ करने का प्रयास करना उपयोगी हो सकता है - कहते हैं कि एक त्रुटि संदेश लॉग करें। लेकिन उस बिंदु पर कोई गारंटी नहीं है कि यह निष्पादित हो जाएगा। यदि आपका JVM OOMing है, तो लॉग ऑन करने का प्रयास अधिक String
s आवंटित कर सकता है जो किसी अन्य OOM को ट्रिगर करता है।
बहुपरत वातावरण में, आप अक्सर इसे पकड़ना चाहते हैं! जब आप इसे पकड़ लेते हैं, तो इसे लॉग इन करें, और पूरे आवेदन को समाप्त करें! यदि आप ऐसा नहीं करते हैं, तो कुछ महत्वपूर्ण भाग को करने वाले कुछ धागे मृत हो जाएंगे, और बाकी एप्लिकेशन यह सोचेंगे कि सब कुछ सामान्य है। उसमें से, कई अवांछित परिस्थितियाँ हो सकती हैं। एक छोटी से छोटी समस्या यह है कि आप आसानी से समस्या की जड़ को खोजने में सक्षम नहीं होंगे, अगर दूसरे धागे काम न करने के कारण कुछ अपवादों को फेंकना शुरू कर दें।
उदाहरण के लिए, आमतौर पर लूप होना चाहिए:
try {
while (shouldRun()) {
doSomething();
}
}
catch (Throwable t) {
log(t);
stop();
System.exit(1);
}
यहां तक कि कुछ मामलों में, आप अलग-अलग त्रुटियों को अलग-अलग तरीके से संभालना चाहेंगे, उदाहरण के लिए, आउटऑफ़मेरीऑरर पर आप नियमित रूप से आवेदन को बंद करने में सक्षम होंगे (यहां तक कि शायद कुछ स्मृति मुक्त करें, और जारी रखें), कुछ अन्य पर, ऐसा बहुत कुछ नहीं है जो आप कर सकते हैं।
OutOfMemoryError
और जारी रखना नासमझी है क्योंकि आपका कार्यक्रम तब अपरिभाषित स्थिति में होता है ।
एक Error
आम तौर पर पकड़ा नहीं किया जाना चाहिए , क्योंकि यह एक असामान्य स्थिति है कि हो कभी नहीं करना चाहिए इंगित करता है ।
Error
कक्षा के लिए जावा एपीआई विशिष्टता से :
इसका
Error
एक उपवर्गThrowable
गंभीर समस्याओं को इंगित करता है जिसे एक उचित अनुप्रयोग को पकड़ने की कोशिश नहीं करनी चाहिए। अधिकांश ऐसी त्रुटियां असामान्य स्थिति हैं। [...]विधि को इसके थ्रो में घोषित करने के लिए किसी त्रुटि के किसी उपवर्ग का उपयोग करने की आवश्यकता नहीं होती है, जिसे विधि के निष्पादन के दौरान फेंक दिया जा सकता है, लेकिन पकड़ा नहीं जाता है, क्योंकि ये त्रुटियां असामान्य स्थितियां हैं जो कभी नहीं होनी चाहिए।
जैसा कि विनिर्देश का उल्लेख है, एक Error
केवल उन परिस्थितियों में फेंका जाता है जो संभावनाएं हैं, जब ऐसा Error
होता है, तो बहुत कम आवेदन होता है, और कुछ परिस्थितियों में, जावा वर्चुअल मशीन स्वयं एक अस्थिर स्थिति में हो सकती है (जैसे VirtualMachineError
)
हालाँकि, Error
इसका एक उपवर्ग है, Throwable
जिसका अर्थ है कि इसे एक try-catch
खंड द्वारा पकड़ा जा सकता है , लेकिन यह वास्तव में आवश्यक नहीं है, क्योंकि आवेदन एक असामान्य स्थिति में होगा जब एक Error
JVM द्वारा फेंक दिया जाता है।
वहाँ भी धारा में इस विषय पर एक छोटा भाग है 11.5 अपवाद पदानुक्रम के जावा भाषा विशिष्टता, 2 संस्करण ।
और कुछ अन्य मामले हैं जहां यदि आप एक त्रुटि पकड़ते हैं, तो आपको इसे वापस लेना होगा । उदाहरण के लिए थ्रेड-डाउन को कभी भी नहीं पकड़ा जाना चाहिए, इससे बड़ी समस्या यह हो सकती है कि आप इसे एक निहित वातावरण में पकड़ सकते हैं (उदाहरण के लिए एक एप्लिकेशन सर्वर):
एक एप्लिकेशन को इस वर्ग के उदाहरणों को तभी पकड़ना चाहिए जब इसे एसिंक्रोनसली समाप्त होने के बाद साफ किया जाना चाहिए। यदि थ्रेडडॉट को एक विधि द्वारा पकड़ा जाता है, तो यह महत्वपूर्ण है कि इसे फिर से उखाड़ दिया जाए ताकि थ्रेड वास्तव में मर जाए।
Error
।
बहुत, बहुत कम ही।
मैंने इसे केवल एक बहुत विशिष्ट ज्ञात मामलों के लिए किया था। उदाहरण के लिए, java.lang.UnsatisfiedLinkError को फेंक दिया जा सकता है अगर दो स्वतंत्रता क्लासलोडर डीएलएल को लोड करते हैं। (मैं सहमत हूं कि मुझे जार को एक साझा क्लास लोडर में स्थानांतरित करना चाहिए)
लेकिन सबसे आम मामला यह है कि उपयोगकर्ता को शिकायत करने पर क्या हुआ, यह जानने के लिए आपको लॉगिंग की आवश्यकता है। आप उपयोगकर्ता को संदेश या पॉपअप चाहते हैं, बल्कि तब चुपचाप मर जाते हैं।
यहां तक कि सी / सी ++ में प्रोग्रामर, वे एक त्रुटि पॉप करते हैं और कुछ लोगों को बताते हैं जो इसे बाहर निकलने से पहले नहीं समझते हैं (उदाहरण के लिए स्मृति विफलता)।
Android ऐप्लिकेशन में मैं java.lang.VerifyError को पकड़ रहा हूं । एक पुस्तकालय जो मैं उपयोग कर रहा हूं वह ओएस के पुराने संस्करण वाले उपकरणों में काम नहीं करेगा और पुस्तकालय कोड ऐसी त्रुटि को फेंक देगा। मैं निश्चित रूप से रनटाइम पर OS के संस्करण की जाँच करके त्रुटि से बच सकता था, लेकिन:
आदर्श रूप से हमें त्रुटियों को संभालना / पकड़ना नहीं चाहिए। लेकिन ऐसे मामले भी हो सकते हैं जहां हमें रूपरेखा या आवेदन की आवश्यकता के आधार पर करने की आवश्यकता है। कहो कि मेरे पास एक XML पार्सर डेमॉन है जो डोम पार्सर को लागू करता है जो अधिक मेमोरी का उपभोग करता है। यदि कोई आवश्यकता है जैसे कि Parser थ्रेड की मृत्यु नहीं होनी चाहिए जब इसे OutOfMemoryError मिलता है , इसके बजाय इसे संभालना चाहिए और एप्लिकेशन / फ्रेमवर्क के व्यवस्थापक को एक संदेश / मेल भेजना चाहिए।
एक त्रुटि है जब JVM उम्मीद के मुताबिक काम नहीं कर रहा है, या करने की कगार पर है। यदि आप कोई त्रुटि पकड़ते हैं, तो इस बात की कोई गारंटी नहीं है कि कैच ब्लॉक चलेगा, और इससे भी कम कि यह अंत तक चलेगा।
यह चल रहे कंप्यूटर, वर्तमान मेमोरी स्थिति पर भी निर्भर करेगा, इसलिए अपना सर्वश्रेष्ठ परीक्षण करने, प्रयास करने और करने का कोई तरीका नहीं है। आपके पास केवल एक सुखद परिणाम होगा।
आप अपने कोड की पठनीयता को भी कम कर देंगे।