2012-06-13 14 views
17

मैंने सुना है कि java.lang.Error को पकड़ना बुरा अभ्यास माना जाता है। मैं वर्तमान में एक .dll लोड कर रहा हूं जिसे PATH पर होने की गारंटी नहीं है, और यदि उपयोगकर्ता ऐसा नहीं है, तो उपयोगकर्ता द्वारा कॉन्फ़िगर किए गए स्थान पर स्विच करना चाहते हैं।जावा त्रुटियों को पकड़ना

try { 
    System.loadLibrary("HelloWorld"); 
} catch(UnsatisfiedLinkError ule){ 
    System.load("C:/libraries/HelloWorld.dll"); 
} 

क्या ऐसा करने का कोई बेहतर तरीका है? या UnsatisfiedLinkError यहां स्वीकार्य है?

+5

यहां सही रूपांतरण के बारे में कोई जानकारी नहीं है, लेकिन आप यह जांच सकते हैं कि फ़ाइल कोशिश करने से पहले मौजूद है या नहीं ... ['नई फ़ाइल (" पथ/helloworld.dll ") .exists()'] (http: // docs। oracle.com/javase/7/docs/api/java/io/File.html#exists%28%29) .... (संपादित करें: गलत सुझाव, मैं कोड को गलत तरीके से पढ़ता हूं) –

+5

मैं इसे एक स्वीकार्य कामकाज मानता हूं। –

+0

@Slanec आपको 'java.library.path' –

उत्तर

16

तकनीकी रूप से समस्या को दूर करने के तरीके के बारे में सलाह देने के अलावा, मैं एक पल लेना चाहता हूं और समझाता हूं कि इसे पहली जगह "खराब अभ्यास" क्यों माना जाता है।

चलिए Error कक्षा को स्पष्ट करने के द्वारा शुरू करते हैं।


जावा में, त्रुटियों और अपवाद (जो मुख्य प्रकार हैं) फेंक दिए जाते हैं। उपरोक्त में से एक को फेंकना throw कीवर्ड का उपयोग करके किया जाता है। प्रत्येक वर्ग जो मूल java.lang.Throwable फैलाता है उसे फेंक दिया जा सकता है।

दो वर्ग हैं जो मूल Throwable कक्षा से प्राप्त होते हैं: Exception और Error। उन दोनों के बीच अंतर उनके दस्तावेजों में समझाया गया है:

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

Source

वर्ग अपवाद और उसके उपवर्गों फेंकने योग्य कि की स्थिति को इंगित करता है का एक रूप है कि एक उचित आवेदन को पकड़ने के लिए चाहते हो सकता है कर रहे हैं ।

Source


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

यह RuntimeException के लिए भी सही है, लेकिन इसका उपयोग उच्च स्तरीय परत (उदा। विधियों) के साथ समस्या को इंगित करने के लिए किया जाता है। जबकि Error निम्न-स्तर की समस्या इंगित करता है (उदा। रनटाइम)।


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

हां, UnsatisfiedLinkError को पकड़ना पूरी तरह से उचित है, क्योंकि आपका एप्लिकेशन इससे पुनर्प्राप्त हो सकता है।


मैं ऊपर (और अधिक विस्तार में और उदाहरण के साथ) और एक article on my Blog में कुछ विस्तारित जानकारी को कवर किया।

+0

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

+0

यदि एप्लिकेशन किसी त्रुटि से पुनर्प्राप्त नहीं हो सकता है तो आप इसे पकड़ने से भी बदतर नहीं हैं, है ना? – simon

+0

@ सिमॉन अगर आप वास्तव में त्रुटि से ठीक नहीं हो सकते हैं, तो आप इसे पकड़ते समय क्या करने जा रहे हैं? यदि आवेदन अब और काम नहीं करता है, तो इसे क्यों चलाना जारी रखें? –

0

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

+0

लाइब्रेरी चेक के बाद और लोड से पहले हटा दी जा सकती है, इसलिए कोशिश पकड़ने की अभी भी आवश्यकता है। –

0

यदि आप रक्षात्मक कोडिंग कर रहे हैं और किसी समस्या से पुनर्प्राप्त हो सकते हैं, तो यह जावा Error नहीं है। यदि ऐसी कोई समस्या बहुत संभावना नहीं है, तो Exception का उप-वर्ग बनाएं और उसे फेंक दें और उसे पकड़ें। यदि ऐसी कोई समस्या हो सकती है, तो उसे Exception भी फेंकना नहीं चाहिए; लेकिन, नियमित कोड प्रवाह का हिस्सा होना चाहिए।

try { 
    if (config.hasCustomDLL()) { 
    System.load(config.getCustomDLL()); 
    } else { 
    System.loadLibrary(Config.DEFAULT_DLL); 
    } 
} catch (UnstatisfiedLinkError e) { 
    System.out.println("Error loading DLL: " + e); 
} 

Errors वास्तव में बुरा विफलताओं के लिए हैं, प्राप्य नहीं "विफलताएं" जो वास्तव में भी विफलताओं अगर वहाँ एक उपयुक्त समाधान नहीं है नहीं कर रहे हैं। सिस्टम को कई तरीकों से कॉन्फ़िगर करने की क्षमता के साथ विफलता को संभालने के लिए डिज़ाइन की गई प्रणाली को अधिभारित न करें।

0

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

यदि आपको कोई त्रुटि पकड़ने की आवश्यकता है, तो इसे एक संकीर्ण, नियंत्रित फेशन में करें।

संबंधित मुद्दे