Java.lang.Error कब पकड़ना है?


जवाबों:


101

आम तौर पर, कभी नहीं।

हालांकि, कभी-कभी आपको विशिष्ट त्रुटियों को पकड़ने की आवश्यकता होती है।

यदि आप फ्रेमवर्क-ईश कोड (तृतीय पक्ष कक्षाएं लोड कर रहे हैं) लिख रहे हैं, तो इसे पकड़ना बुद्धिमान हो सकता है LinkageError(कोई वर्ग दोष नहीं पाया गया, असंतुष्ट लिंक, असंगत वर्ग परिवर्तन)।

मैंने कुछ बेवकूफ 3-पार्टी कोड को उपवर्गों को फेंकते हुए भी देखा है Error, इसलिए आपको उन्हें भी संभालना होगा।

वैसे, मुझे यकीन नहीं है कि इससे उबरना संभव नहीं है OutOfMemoryError


3
कि मुझे DLL को लोड करने के लिए वास्तव में करना था, अगर वे सही ढंग से कॉन्फ़िगर नहीं किए गए थे तो विफल हो जाएंगे। इस आवेदन के मामले में एक घातक त्रुटि नहीं।
मारियो ऑर्टगॉन

7
यह कभी-कभी आउटऑफमेमोरीइर्रर को पकड़ने के लिए समझ में आता है - उदाहरण के लिए जब आप बड़ी सरणी सूची बना रहे हैं।
स्पेसट्रेकर

3
@स्पेसTrucker: क्या यह दृष्टिकोण मल्टीथ्रेडेड अनुप्रयोगों में अच्छी तरह से काम करता है, या क्या कोई महत्वपूर्ण जोखिम है कि अन्य थ्रेड्स में छोटे आवंटन इसके कारण विफल हो जाते हैं? … शायद तभी जब आपके सरणियों को आवंटित किया जाना काफी छोटा था, लेकिन किसी और के लिए कुछ भी नहीं छोड़ा।
PJTraill

@PJTraill मुझे इस बारे में निश्चित नहीं है। इसके लिए कुछ वास्तविक विश्व सांख्यिकीय नमूनों की आवश्यकता होगी। मुझे लगा कि मैंने ऐसा कोड देखा है, लेकिन यह याद नहीं कर सकता कि यह कहाँ था।
स्पेसट्रॉकर

51

कभी नहीँ। आप कभी भी यह सुनिश्चित नहीं कर सकते हैं कि एप्लिकेशन कोड की अगली पंक्ति को निष्पादित करने में सक्षम है। यदि आप एक प्राप्त करते हैं OutOfMemoryError, तो आपके पास कोई गारंटी नहीं है कि आप मज़बूती से कुछ भी करने में सक्षम होंगे । RuntimeException को पकड़ो और अपवाद की जाँच की, लेकिन त्रुटियां कभी नहीं।

http://pmd.sourceforge.net/rules/strictexception.html


27
नेवर से नेवर। हमारे पास परीक्षण कोड है जो "असत्य का दावा करता है;" फिर सुनिश्चित करता है कि -ea ध्वज सेट है, यह सुनिश्चित करने के लिए जोर देता है। इसके अलावा ... हाँ, शायद कभी नहीं ;-)
डाकू प्रोग्रामर

3
कैसे एक सर्वर एप्लिकेशन के बारे में जो श्रमिक थ्रेड से अनुरोध करता है। हो सकता है कि किसी भी त्रुटि को फंसाने के लिए श्रमिक थ्रेड पर थ्रोबेबल को पकड़ने के लिए समझ में न आए, और कम से कम कोशिश करें और क्या गलत हो गया है?
लेह

11
कभी नहीं ... सिवाय जब आप बिल्कुल की जरूरत है। कभी भी एक मजबूत शब्द नहीं है और हमेशा नियमों के अपवाद हैं। यदि आप एक रूपरेखा का निर्माण कर रहे हैं, तो यह संभव नहीं है कि आपको कुछ त्रुटियों को पकड़ना होगा और संभालना होगा, भले ही वह केवल लॉग करना हो।
रॉबिन

कैसे के बारे में त्रुटि NoSuchMethodError कि तीसरे पक्ष के पुस्तकालय विधियों से आ रहा है?
ha9u63ar

@OutlawProgrammer सिर्फ रिकॉर्ड के लिए, एक ही परीक्षण करने के अन्य तरीके हैं:boolean assertionsEnabled = false; assert assertionsEnabled = true;
shmosel

16

आम तौर पर आपको हमेशा java.lang.Errorलॉग को पकड़ना चाहिए और उसे लिखना चाहिए या उसे उपयोगकर्ता को दिखाना चाहिए। मैं समर्थन में काम करता हूं और दैनिक देखता हूं कि प्रोग्रामर यह नहीं बता सकते कि एक कार्यक्रम में क्या हुआ है।

यदि आपके पास डेमन धागा है तो आपको इसे समाप्त होने से रोकना चाहिए। अन्य मामलों में आपका आवेदन सही ढंग से काम करेगा।

आपको केवल java.lang.Errorउच्चतम स्तर पर पकड़ चाहिए ।

यदि आप त्रुटियों की सूची को देखते हैं तो आप देखेंगे कि अधिकांश को संभाला जा सकता है। उदाहरण के लिए ZipErrorभ्रष्ट ज़िप फ़ाइलों को पढ़ने पर होता है।

सबसे आम त्रुटियां हैं OutOfMemoryErrorऔर NoClassDefFoundError, जो कि ज्यादातर मामलों में रनटाइम की समस्याएं हैं।

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

int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];

उत्पादन कर सकता है, OutOfMemoryErrorलेकिन यह एक रनटाइम समस्या है और आपके कार्यक्रम को समाप्त करने का कोई कारण नहीं है।

NoClassDefFoundErrorज्यादातर तब होता है जब एक पुस्तकालय मौजूद नहीं होता है या यदि आप किसी अन्य जावा संस्करण के साथ काम करते हैं। यदि यह आपके कार्यक्रम का एक वैकल्पिक हिस्सा है तो आपको अपना कार्यक्रम समाप्त नहीं करना चाहिए।

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


मैं उन मामलों में इसके बेहतर होने पर संदेह करूँगा कि उचित अलर्ट के साथ डेमॉन को विफल करने के लिए, फिर इसके जीवित रहने की संभावना एक असफल jvm पर कुछ ईथर भूत के रूप में जहां यह गलत बहाना दे सकता है कि यह वास्तव में जीवित है और कुछ कर रहा है
एंड्रयू नॉर्मन

OutOfMemoryErrorकोई रनटाइम त्रुटि नहीं है कोई गारंटी नहीं है कि एप्लिकेशन इससे पुनर्प्राप्त कर सकता है। यदि आप भाग्यशाली हैं, तो आपको OOM मिल सकता है, new byte[largeNumber]लेकिन यदि वह आवंटन OOM का कारण बनने के लिए पर्याप्त नहीं था, तो इसे अगली पंक्ति या अगले थ्रेड में ट्रिगर किया जा सकता है। यह रनटाइम समस्या है क्योंकि यदि lengthअविश्वासित इनपुट है तो इसे कॉल करने से पहले मान्य किया जाना चाहिए new byte[]
जीयॉन्ग किम

NoClassDefFoundErrorकहीं भी हो सकता है , क्योंकि यह संकलित है जब संकलित जावा कोड एक वर्ग नहीं पा सकता है। यदि आपका JDK गलत है तो वह java.util.*वर्ग का उपयोग करने की कोशिश कर सकता है और इसके खिलाफ प्रोग्राम करना व्यावहारिक रूप से असंभव है। यदि आप वैकल्पिक रूप से एक निर्भरता सहित हैं, तो आपको ClassLoaderयह जांचने के लिए उपयोग करना चाहिए कि क्या यह मौजूद है, जो फेंकता है ClassNotFoundException
जीयॉन्ग किम

1
ZipErrorइंगित करता है कि jar फ़ाइल जिसमें कक्षाएं हैं एक दूषित ज़िप फ़ाइल है। यह काफी गंभीर मुद्दा है और इस बिंदु पर आप किसी भी कोड पर विश्वास नहीं कर सकते हैं जो निष्पादित हो जाता है और इससे "पुनर्प्राप्त" करने के प्रयास के लिए यह गैर जिम्मेदाराना होगा।
जीयॉन्ग किम

2
सामान्य तौर पर, शीर्ष स्तर पर इसे पकड़ने java.lang.Errorया java.lang.Throwableइसके साथ कुछ करने का प्रयास करना उपयोगी हो सकता है - कहते हैं कि एक त्रुटि संदेश लॉग करें। लेकिन उस बिंदु पर कोई गारंटी नहीं है कि यह निष्पादित हो जाएगा। यदि आपका JVM OOMing है, तो लॉग ऑन करने का प्रयास अधिक Strings आवंटित कर सकता है जो किसी अन्य OOM को ट्रिगर करता है।
जीयॉन्ग किम

15

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

उदाहरण के लिए, आमतौर पर लूप होना चाहिए:

try {
   while (shouldRun()) {
       doSomething();
   }
}
catch (Throwable t) {
   log(t);
   stop();
   System.exit(1);
}

यहां तक ​​कि कुछ मामलों में, आप अलग-अलग त्रुटियों को अलग-अलग तरीके से संभालना चाहेंगे, उदाहरण के लिए, आउटऑफ़मेरीऑरर पर आप नियमित रूप से आवेदन को बंद करने में सक्षम होंगे (यहां तक ​​कि शायद कुछ स्मृति मुक्त करें, और जारी रखें), कुछ अन्य पर, ऐसा बहुत कुछ नहीं है जो आप कर सकते हैं।


1
मौजूदा शीघ्रता के बजाय पकड़ना OutOfMemoryError और जारी रखना नासमझी है क्योंकि आपका कार्यक्रम तब अपरिभाषित स्थिति में होता है
राएडवल्ड

1
कॉलिंग सिस्टम, एक फेंकने योग्य को पकड़ने पर बाहर निकलने का JVM पर चलने वाली हर चीज को मारने का अनपेक्षित परिणाम है और न केवल प्रश्न में आवेदन। आमतौर पर वेब एप्लिकेशन के लिए एक अच्छा अभ्यास नहीं है जो अन्य वेब एप्लिकेशन के साथ ऐप सर्वर पर होस्ट किया जा सकता है (इसका उल्लेख नहीं करने से यह ऐप सर्वर पर ही प्रभाव डालेगा)।
एंड्रयू नॉर्मन

9

बहुत मुश्किल से।

मैं केवल एक सूत्र के शीर्ष स्तर पर कहना चाहूंगा ताकि ATTEMPT को एक धागा मरने के कारण के साथ एक संदेश जारी किया जा सके।

यदि आप किसी ऐसे ढाँचे में हैं, जो आपके लिए इस तरह का काम करता है, तो इसे ढाँचे में छोड़ दें।


6

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


6

एक Errorआम तौर पर पकड़ा नहीं किया जाना चाहिए , क्योंकि यह एक असामान्य स्थिति है कि हो कभी नहीं करना चाहिए इंगित करता है

Errorकक्षा के लिए जावा एपीआई विशिष्टता से :

इसका Errorएक उपवर्ग Throwable गंभीर समस्याओं को इंगित करता है जिसे एक उचित अनुप्रयोग को पकड़ने की कोशिश नहीं करनी चाहिए। अधिकांश ऐसी त्रुटियां असामान्य स्थिति हैं। [...]

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

जैसा कि विनिर्देश का उल्लेख है, एक Errorकेवल उन परिस्थितियों में फेंका जाता है जो संभावनाएं हैं, जब ऐसा Errorहोता है, तो बहुत कम आवेदन होता है, और कुछ परिस्थितियों में, जावा वर्चुअल मशीन स्वयं एक अस्थिर स्थिति में हो सकती है (जैसे VirtualMachineError)

हालाँकि, Errorइसका एक उपवर्ग है, Throwableजिसका अर्थ है कि इसे एक try-catchखंड द्वारा पकड़ा जा सकता है , लेकिन यह वास्तव में आवश्यक नहीं है, क्योंकि आवेदन एक असामान्य स्थिति में होगा जब एक ErrorJVM द्वारा फेंक दिया जाता है।

वहाँ भी धारा में इस विषय पर एक छोटा भाग है 11.5 अपवाद पदानुक्रम के जावा भाषा विशिष्टता, 2 संस्करण


6

यदि आप एक नई इकाई परीक्षण रूपरेखा बनाने के लिए पर्याप्त पागल हैं, तो आपके परीक्षण धावक को शायद किसी भी परीक्षण मामलों द्वारा java.lang.AssertionError को फेंकने की आवश्यकता होगी।

अन्यथा, अन्य उत्तर देखें।


5

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

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


2
जो वास्तव में एक गैर-मुद्दा है क्योंकि आप बस एस नहीं पकड़ते हैं Error
बॉम्बे

4

बहुत, बहुत कम ही।

मैंने इसे केवल एक बहुत विशिष्ट ज्ञात मामलों के लिए किया था। उदाहरण के लिए, java.lang.UnsatisfiedLinkError को फेंक दिया जा सकता है अगर दो स्वतंत्रता क्लासलोडर डीएलएल को लोड करते हैं। (मैं सहमत हूं कि मुझे जार को एक साझा क्लास लोडर में स्थानांतरित करना चाहिए)

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

यहां तक ​​कि सी / सी ++ में प्रोग्रामर, वे एक त्रुटि पॉप करते हैं और कुछ लोगों को बताते हैं जो इसे बाहर निकलने से पहले नहीं समझते हैं (उदाहरण के लिए स्मृति विफलता)।


3

Android ऐप्लिकेशन में मैं java.lang.VerifyError को पकड़ रहा हूं । एक पुस्तकालय जो मैं उपयोग कर रहा हूं वह ओएस के पुराने संस्करण वाले उपकरणों में काम नहीं करेगा और पुस्तकालय कोड ऐसी त्रुटि को फेंक देगा। मैं निश्चित रूप से रनटाइम पर OS के संस्करण की जाँच करके त्रुटि से बच सकता था, लेकिन:

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

3

यह एक परीक्षण के माहौल में java.lang.AssertionError को पकड़ने के लिए काफी आसान है ...


आप किस मूल्य को जोड़ने की कोशिश कर रहे हैं?
lpapp

परीक्षण सूट के मूल्य को जोड़ते हुए गर्भपात नहीं किया गया
जोनो

2

आदर्श रूप से हमें त्रुटियों को संभालना / पकड़ना नहीं चाहिए। लेकिन ऐसे मामले भी हो सकते हैं जहां हमें रूपरेखा या आवेदन की आवश्यकता के आधार पर करने की आवश्यकता है। कहो कि मेरे पास एक XML पार्सर डेमॉन है जो डोम पार्सर को लागू करता है जो अधिक मेमोरी का उपभोग करता है। यदि कोई आवश्यकता है जैसे कि Parser थ्रेड की मृत्यु नहीं होनी चाहिए जब इसे OutOfMemoryError मिलता है , इसके बजाय इसे संभालना चाहिए और एप्लिकेशन / फ्रेमवर्क के व्यवस्थापक को एक संदेश / मेल भेजना चाहिए।


1

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


1

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


1

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

यह चल रहे कंप्यूटर, वर्तमान मेमोरी स्थिति पर भी निर्भर करेगा, इसलिए अपना सर्वश्रेष्ठ परीक्षण करने, प्रयास करने और करने का कोई तरीका नहीं है। आपके पास केवल एक सुखद परिणाम होगा।

आप अपने कोड की पठनीयता को भी कम कर देंगे।

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