चेक किए गए अपवादों से कैसे निपटें जो कभी भी फेंके नहीं जा सकते


35

उदाहरण:

foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");

चूंकि एन्कोडिंग हार्डकोड और सही है, इसलिए निर्माता विनिर्देश में घोषित UnsupportedEncodingException को कभी नहीं फेंकेंगे (जब तक कि जावा कार्यान्वयन टूट नहीं जाता है, जिस स्थिति में मैं वैसे भी खो जाता हूं)। वैसे भी, जावा मुझे उस अपवाद से निपटने के लिए वैसे भी मजबूर करता है।

वर्तमान में, यह ऐसा दिखता है

try {
    foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");
}
catch(UnsupportedEncodingException e) { /* won't ever happen */ }

किसी भी विचार यह कैसे बेहतर बनाने के लिए?


4
वास्तविक चुनौती के लिए, यह सुनिश्चित करने के लिए एक इकाई परीक्षण लिखें कि यह पकड़ वास्तव में काम करती है।
जे एलस्टन

1
`नई असंभव फेंक (" ब्रह्मांड को रिबूट करें। चीजें गड़बड़ हो गई हैं ", ई);
क्रिस कुडमोर

1
"कभी नहीं होगा" ...

Thorbjørn Ravn Andersen: यह कार्यक्रम को बदलने के बाद हो सकता है, लेकिन कम से कम इसकी वर्तमान स्थिति में, इनपुट डेटा का कोई सेट अपवाद को ट्रिगर नहीं कर सकता है।
user281377

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

जवाबों:


27

मेरी आदत सिर्फ सुरक्षित तरफ रहने की है, assertकैच ब्लॉक में डालने की है । कोई व्यक्ति tryबाद में ब्लॉक की सामग्री को बदल सकता है , और आप जानना चाहते हैं कि क्या कोड विफल नहीं होता है?


अच्छा विचार; एक साधारण assert false;बहुत अव्यवस्था नहीं जोड़ता है और यह स्पष्ट करता है कि मुझे लगता है कि पकड़ ब्लॉक कभी दर्ज नहीं किया जाएगा।
user281377

5
@ammoQ, या आप अपने इरादे को स्पष्ट करने के लिए एक संदेश भी जोड़ सकते हैं assert false : "should never happen":।
Péter Török

13
इससे भी बेहतर, "ऐसा कभी नहीं होना चाहिए क्योंकि जावा को चारसेट ISO-8859-1 की आवश्यकता होती है।"
dan04

3
assertतात्पर्य मुखरता सक्षम हैं। मैं एक फेंक देता हूं UnexpectedException(जिसमें मुझे स्टैक ट्रेस करने का लाभ भी है ...)।
चोप

35

अगर मुझे हर बार एक लॉग / त्रुटि दिखाई दी, "यह कभी भी नहीं होना चाहिए", मुझे दिया गया ... मेरे पास दो सेंट हैं। फिर भी...

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

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


28

मैंने हमेशा इसे इस तरह किया है:

try {
    foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");
} catch(UnsupportedEncodingException e) {
    throw new AssertionError(e);
}

थोड़ा वर्बोस हो सकता है (जावा है ...), लेकिन कम से कम आपको असंभव होने पर एक जोरदार त्रुटि मिलेगी।

यदि जावा कार्यान्वयन टूट गया है, तो आप असंभव को नजरअंदाज करने के बजाय, जितनी जल्दी हो सके उतनी अच्छी त्रुटि संदेश प्राप्त करना चाहेंगे। और यहां तक ​​कि अगर जावा कार्यान्वयन टूट नहीं गया है, तो कोई आपके कोड को बदल सकता है "UTF8"(उफ़ - यह होना चाहिए था "UTF-8"?)।

यह पहली बार में एक रनटाइम अपवाद होना चाहिए था। JDK इस तरह के गलत विकल्पों से भरा है।


4
वास्तविक खराब विचलन (या यदि आप चाहते हैं तो चूक) यह है कि उन 6 वर्णों के लिए कोई पूर्व-परिभाषित चारसेट उदाहरण नहीं हैं जिनकी जावा को आवश्यकता है। foobar = new InputStreamReader(p.getInputStream(), Charset.ISO_8859_1);- अब यह अच्छा नहीं होगा और एक बार और हमेशा के लिए किसी भी गलती से बचें?
user281377

3
अमरूद पुस्तकालय में इन चीजों के टन हैं। जीवन को आसान बनाता है।

3
जावा 1.7+ में चारसेट कॉन्स्टैंट परिभाषित हैं: docs.oracle.com/javase/7/docs/api/java/nio/charset/… । उन्हें इस तरह का उपयोग करें: StandardCharsets.UTF_8.displayName ()
माइकल

4

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


4

इन अपवादों का एक हिस्सा जो मुझे सबसे अधिक परेशान करता है, वह यह है कि यह मेरे कोड कवरेज को नुकसान पहुंचाता है।

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

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

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

हालांकि, एक टिप्पणी के रूप में, अमरूद और अन्य पुस्तकालयों में इस दर्द को कम करने के तरीके हैं - लेकिन यह मूल रूप से एक ही रणनीति है। अपने मुख्य कोड को कवरेज में हिट न करने के लिए झुंझलाहट को बंद करें।

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