जावा में ट्रू-वे सॉल्यूशन: 2 स्ट्रिंग्स से 2 नंबरों को पार्स करें और फिर अपनी राशि लौटाएं


84

एक मूर्खतापूर्ण प्रश्न। कोड दिया:

public static int sum(String a, String b) /* throws? WHAT? */ {
  int x = Integer.parseInt(a); // throws NumberFormatException
  int y = Integer.parseInt(b); // throws NumberFormatException
  return x + y;
}

क्या आप बता सकते हैं कि यह जावा अच्छा है या नहीं? मैं जो बात कर रहा हूं, NumberFormatExceptionवह अनियंत्रित अपवाद है। आपको इसे हस्ताक्षर के भाग के रूप में निर्दिष्ट करने की आवश्यकता नहीं हैsum() । इसके अलावा, जहां तक ​​मैं समझता हूं, अनियंत्रित अपवादों का विचार केवल यह संकेत देना है कि प्रोग्राम का कार्यान्वयन गलत है, और इससे भी अधिक, अनियंत्रित अपवादों को पकड़ना एक बुरा विचार है, क्योंकि यह रनटाइम पर खराब प्रोग्राम को ठीक करने जैसा है

क्या कोई स्पष्ट करेगा कि क्या:

  1. मुझे NumberFormatExceptionविधि के हस्ताक्षर के एक भाग के रूप में निर्दिष्ट करना चाहिए ।
  2. मुझे अपने स्वयं के चेक किए गए अपवाद को परिभाषित करना चाहिए ( BadDataException), NumberFormatExceptionविधि के अंदर संभालें और इसे फिर से फेंक दें BadDataException
  3. मुझे अपने स्वयं के चेक किए गए अपवाद को परिभाषित करना चाहिए ( BadDataException), दोनों स्ट्रिंग को नियमित अभिव्यक्तियों की तरह सत्यापित करें और BadDataExceptionअगर यह मेल नहीं खाता है तो मुझे फेंक दें ।
  4. आपका विचार?

अपडेट :

कल्पना कीजिए, यह एक ओपन-सोर्स फ्रेमवर्क नहीं है, जिसे आपको किसी कारण से उपयोग करना चाहिए। आप विधि के हस्ताक्षर को देखते हैं और सोचते हैं - "ठीक है, यह कभी नहीं फेंकता है"। फिर, किसी दिन, आपको एक अपवाद मिला। क्या यह सामान्य है?

अपडेट 2 :

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

समस्या की परिभाषा इस प्रकार है: आपके पास एक डेटा स्रोत है जहाँ संख्याएँ Strings के रूप में संग्रहीत हैं । यह स्रोत XML फ़ाइल, वेब पेज, डेस्कटॉप विंडो 2 एडिट बॉक्स के साथ हो सकता है, जो भी हो।

आपका लक्ष्य तर्क को लागू करना है जो इन 2 Stringएस को लेता है , उन्हें एस में कनवर्ट intकरता है और संदेश बॉक्स को यह कहते हुए प्रदर्शित करता है कि "योग xxx है"।

इससे कोई फर्क नहीं पड़ता कि आप इसे डिजाइन / कार्यान्वित करने के लिए किस दृष्टिकोण का उपयोग करते हैं, आपके पास आंतरिक कार्यक्षमता के ये 2 बिंदु होंगे :

  1. वह स्थान जहाँ आप रूपांतरित Stringहोते हैंint
  2. ऐसी जगह जहां आप 2 intएस जोड़ते हैं

मेरी मूल पोस्ट का प्राथमिक प्रश्न है:

Integer.parseInt()सही स्ट्रिंग को पारित करने की अपेक्षा करता है । जब भी आप एक खराब स्ट्रिंग पास करते हैं , तो इसका मतलब है कि आपका प्रोग्राम गलत है (" आपका उपयोगकर्ता एक बेवकूफ है")। आपको कोड का टुकड़ा लागू करने की आवश्यकता है जहां एक ओर आपके पास Integer.parseInt () MUST शब्दार्थ के साथ और दूसरी ओर आपको इनपुट गलत होने पर मामलों के साथ ठीक होने की आवश्यकता है - SHOULD शब्दार्थ

इसलिए, संक्षेप में: यदि मैं केवल MUST पुस्तकालयों को लागू करूं तो मैं SHOULD शब्दार्थ को कैसे लागू कर सकता हूं ।


13
यह किसी भी तरह से एक बेवकूफ सवाल नहीं है। वास्तव में यह एक बहुत अच्छा है! मुझे पूरा यकीन नहीं है कि मैं कौन सा विकल्प चुनूंगा।
मार्टिन

1
आपके अपडेट के लिए: हाँ, असफल-तेज़ सिद्धांत के अनुसार यह आवश्यक रूप से एक बुरी बात नहीं होगी।
जोहान Sjöberg

1
मैं मार्टिन से सहमत हूं। यह जावा प्रोग्रामिंग के पहलुओं में से एक है जो सबसे कम समझा जाता है जिसे कुछ सर्वोत्तम प्रथाओं की आवश्यकता होती है। इस विषय पर पृष्ठों की कमी को बहुत कम देखा जा सकता है, इसके अलावा ओ 'रेली ने कहा "यह है कि यह कैसे किया जाना चाहिए"।
जेम्स पी।

2
दरअसल, यह एक उत्कृष्ट प्रश्न है।
क्रिस कुडमोर

1
बड़ा अच्छा सवाल! साथ ही कुछ बेहतरीन जवाब भी दिए: D
Kheldar

जवाबों:


35

यह अच्छा प्रश्न है। काश और लोग ऐसी बातों के बारे में सोचते।

IMHO, अनियंत्रित अपवादों को फेंकना स्वीकार्य है यदि आपको बकवास पैरामीटर दिए गए हैं।

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

घोषित करने के बारे में throws NumberFormatException- यह उतना उपयोगी नहीं है, क्योंकि नंबरफ़ॉर्मैट अपवाद के अनियंत्रित होने के कारण कुछ नोटिस करेंगे। हालांकि, आईडीई इसका उपयोग कर सकता है और try/catchसही तरीके से लपेटने की पेशकश कर सकता है। एक अच्छा विकल्प के रूप में अच्छी तरह से javadoc का उपयोग करने के लिए है:

/**
 * Adds two string numbers
 * @param a
 * @param b
 * @return
 * @throws NumberFormatException if either of a or b is not an integer
 */
public static int sum(String a, String b) throws NumberFormatException {
    int x = Integer.parseInt(a); 
    int y = Integer.parseInt(b); 
    return x + y;
}

संपादित करें :
टिप्पणीकारों ने मान्य बिंदु बनाए हैं। आपको यह विचार करने की आवश्यकता है कि इसका उपयोग कैसे किया जाएगा और आपके ऐप का समग्र डिज़ाइन।

यदि विधि का उपयोग सभी जगह किया जाएगा, और यह महत्वपूर्ण है कि सभी कॉल करने वाले समस्याओं को संभालते हैं, तो चेक को अपवाद के रूप में फेंकने के तरीके को घोषित करें (समस्याओं से निपटने के लिए कॉल करने के लिए मजबूर करें), लेकिन try/catchब्लॉक के साथ कोड को अव्यवस्थित करना ।

यदि दूसरी तरफ हम इस पद्धति का उपयोग कर रहे हैं, जिस डेटा पर हम भरोसा करते हैं, तो इसे ऊपर घोषित करें, क्योंकि यह कभी भी विस्फोट होने की उम्मीद नहीं है और आप अनिवार्य रूप से अनावश्यक try/catchब्लॉकों के कोड अव्यवस्था से बचें ।


6
समस्या यह है कि अनियंत्रित अपवादों को अक्सर नजरअंदाज कर दिया जाता है और आपके कॉल स्टैक को समाप्त कर सकता है, आपके ऐप के कुछ हिस्सों में कहर बरपाता है जो पता नहीं है कि नीचे क्या निहित है। प्रश्न वास्तव में है कि कौन सा कोड यह जांचना चाहिए कि इनपुट मान्य है या नहीं।
G_H

1
@G_H के पास एक बिंदु है। जावा ट्यूटोरियल्स यह कहते हैं: "यदि किसी ग्राहक से किसी अपवाद से उबरने की अपेक्षा की जा सकती है, तो उसे एक अपवाद बना दें। यदि कोई ग्राहक अपवाद से उबरने के लिए कुछ नहीं कर सकता है, तो उसे अनियंत्रित अपवाद बनाएं"। सवाल यह है कि कहाँ RuntimeExceptionसंभाला जाना चाहिए ? क्या यह कॉलर होना चाहिए या अपवाद को तैरने के लिए छोड़ दिया जाना चाहिए? यदि हां, तो इसे कैसे संभाला जाना चाहिए?
जेम्स पी।

1
आंशिक रूप से इसका उत्तर देने के लिए मैंने दो दृष्टिकोण देखे हैं: पहला है Exceptionsनिचली परतों से अवरोधन करना और उन्हें उच्च स्तर के अपवादों में लपेटना जो कि अंतिम उपयोगकर्ता के लिए अधिक सार्थक हैं और दूसरा एक अनकैप्ड अपवाद हैंडलर का उपयोग करना है जिसे प्रारंभिक रूप में देखा जा सकता है एप्लिकेशन लॉन्चर।
जेम्स पी।

2
आईएमएचओ जावाडॉक में नंबरफ़ॉर्मैट अपवाद है जो बहुत महत्वपूर्ण है। इसे throwsक्लॉज में डालना एक अच्छा जोड़ है, लेकिन इसकी आवश्यकता नहीं है।
डोरस

3
करने के लिए "अपने विधि के कॉलर पता कर सकते हैं इससे पहले कि वे इसे कहते हैं यदि उनके तार नंबर या नहीं हैं, इसलिए गुजर बकवास में परिहार्य है" : यह वास्तव में सच नहीं है। यह सत्यापित करने का एकमात्र सरल तरीका है कि स्ट्रिंग स्ट्रिंग int के रूप में इसे आज़माती है। हालाँकि आप कुछ अपफ्रंट चेक करना चाहते हैं, लेकिन सटीक जाँच काफी PITA है।
Maaartinus 21

49

मेरी राय में जहां तक ​​संभव हो अपवाद अपवाद को संभालना बेहतर होगा। इसलिए मैं हस्ताक्षर पसंद करूंगा

 public static int sum(int a, int b);

आपके विधि हस्ताक्षर से मैं कुछ भी नहीं बदलूंगा। या तो तुम हो

  • प्रोग्रामिक रूप से गलत मान का उपयोग करते हुए, जहाँ आप अपने निर्माता एल्गोरिथ्म को मान्य कर सकते हैं
  • या जैसे, उपयोगकर्ता इनपुट से मान भेजना, जिस स्थिति में मॉड्यूल को सत्यापन करना चाहिए

इसलिए, इस मामले में अपवाद हैंडलिंग एक प्रलेखन मुद्दा बन जाता है ।


4
यह मुझे पंसद है। यह उपयोगकर्ता को अनुबंध का पालन करने के लिए मजबूर करता है, और विधि केवल एक ही काम करता है।
क्रिस कुडमोर

मुझे समझ में नहीं आता है कि इस पद्धति का उपयोग उपयोगकर्ता द्वारा a + b करने से अलग कैसे है। हमें इस पद्धति की आवश्यकता क्यों है?
स्वाति

4
@Swati: मुझे लगता है कि यह एक उदाहरण है , जो चीजों को सीधे दिखाने के लिए एक शानदार तकनीक है। योग विधि के रूप में अच्छी तरह से हो सकता है myVeryComplicatedMethodWhichComputesPhoneNumberOfMyIdealMatchGirl (int myID, int myLifeExpectancy) ...
Kheldia

3
पूरी तरह से यहाँ सहमत हूँ। एक sumफ़ंक्शन जो दो संख्याओं की अपेक्षा करता है, दो नंबर प्राप्त करना चाहिए। जिस तरह से आपको मिला है वह sumफ़ंक्शन से संबंधित नहीं है। अपने तर्क को सही ढंग से अलग करें । इसलिए, मैं इसे एक डिज़ाइन मुद्दे से संबंधित करूँगा।
c00kiemon5ter

5

संख्या 4. जैसा कि दिया गया है, इस पद्धति को स्ट्रिंग नहीं लेना चाहिए क्योंकि यह पूर्णांकों को लेना चाहिए। जिस स्थिति में (क्योंकि ओवरफ्लो करने के बजाय जावा लपेटता है) अपवाद की कोई संभावना नहीं है।

 x = sum(Integer.parseInt(a), Integer.parseInt(b))

की तुलना में क्या मतलब है के रूप में एक बहुत स्पष्ट है x = sum(a, b)

आप चाहते हैं कि अपवाद स्रोत (इनपुट) के जितना संभव हो सके।

1-3 विकल्प के रूप में, आप एक अपवाद को परिभाषित नहीं करते हैं क्योंकि आप उम्मीद करते हैं कि आपके कॉलर्स यह मान लें कि अन्यथा आपका कोड विफल नहीं हो सकता है, आप एक अपवाद को परिभाषित करते हैं कि ज्ञात विफलता परिस्थितियों में क्या होता है जो आपके METHOD के लिए अद्वितीय है। Ie यदि आपके पास एक ऐसी विधि है जो किसी अन्य ऑब्जेक्ट के चारों ओर एक आवरण है, और यह एक अपवाद फेंकता है तो इसे पास करें। केवल अगर अपवाद आपकी पद्धति के लिए अद्वितीय है, तो आपको एक कस्टम अपवाद (फ़्रेक्स, अपने उदाहरण में फेंकना चाहिए, यदि योग केवल सकारात्मक परिणाम देने वाला था, तो उसके लिए जाँच करना और अपवाद फेंकना उचित होगा, यदि दूसरी ओर जावा लपेटने के बजाय एक अतिप्रवाह अपवाद फेंक दिया, फिर आप इसे पास करेंगे, इसे अपने हस्ताक्षर में परिभाषित नहीं करेंगे, इसका नाम बदलेंगे, या खाएंगे)।

प्रश्न के अद्यतन के जवाब में अपडेट करें:

इसलिए, संक्षेप में: मैं केवल शाब्दिक पुस्तकालय होने पर SHOULD शब्दार्थ को कैसे लागू कर सकता हूं।

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


यहाँ आपका क्या विचार है? मैं एक ही मुद्दा पाने वाला हूं, भले ही मेरे पास हो sum(int, int)और parseIntFromString(String)। समान कार्यक्षमता प्राप्त करने के लिए, किसी भी स्थिति में, मुझे एक कोड कोड लिखना होगा जहां 2 कॉल टू parseIntFromString()और 1 कॉल टू है sum()। इस मामले पर विचार करें, अगर यह आपके लिए समझ में आता है - मुझे मूल समस्या के दृष्टिकोण से कोई अंतर नहीं दिखता है।
एंड्री एजिबालोव

@ loki2302: बिंदु कॉलर है तो यह तय करने के लिए मिलता है कि एक नंबर नहीं होने पर क्या व्यवहार उचित है। इसके अलावा, यदि वे त्रुटि जांच नहीं करते हैं, तो विफलता एक कदम के करीब होती है जहां मान असाइन किया गया है - डीबगिंग उद्देश्यों के लिए, असाइनमेंट के करीब, डीबगिंग जितना आसान होगा। और यदि आप TDD कर रहे हैं तो कॉलर के लिए उपयुक्त यूनिट टेस्ट लिखने से चूक सकते हैं। मूल रूप से आप नहीं चाहते हैं कि एक विधि x की आपूर्ति की जाने वाली एक स्ट्रिंग हो जिसे एक संख्या माना जाता है और फिर बाद में 5 कक्षाएं और 20 विधि कॉल एक अपवाद को फेंक देती हैं जब आप इसे एक नंबर का इलाज करने का प्रयास करते हैं।
जोर्मेनो

मुझे नहीं मिला। क्या आप यह कहने की कोशिश कर रहे हैं कि int sum(String, String)वास्तविकता में इंटरफ़ेस प्रदान करना कभी संभव नहीं है?
एंड्री एजिबालोव

1
@ loki2302: दिखाए गए कोड को देखते हुए, यह संभव है लेकिन एक बुरा विचार है। यदि स्ट्रिंग में संख्या एक शब्द हो सकती है जहां "2", "दो", "डॉस", "ड्यूक्स", "ज़्वो" सभी को एक ही माना जाता है, तो वह हस्ताक्षर उपयुक्त होगा। लेकिन जैसा कि यह है, विधि को दो तार दिए गए हैं और उन्हें पूर्णांक मानते हैं। आप कभी ऐसा क्यों करना चाहेंगे? यह एक बुरा विचार है।
jmoreno

2
@ loki2302: आपने यह कहते हुए जवाब स्वीकार कर लिया कि बकवास को पास करने के दौरान अनियंत्रित अपवाद को फेंकना ठीक था, लेकिन जोरदार टाइप की गई भाषा का मतलब पास होने से बचना है। एक विधि है कि एक स्ट्रिंग हमेशा एक पूर्णांक मूल्य होने की उम्मीद है सिर्फ परेशानी के लिए पूछ रहा है। यहां तक ​​कि Integer.parseInt उस कुएं के साथ सौदा नहीं करता है (SHOULD होने की उम्मीद इनपुट के खराब होने पर एक अपवाद है, .Net का पूर्णांक है। ट्रीपर्स विधि बहुत बेहतर है, हालांकि जावा के आउट पैरामीटर की कमी इसे कुछ अव्यवहारिक बनाती है)।
jmoreno

3

1. मुझे विधि के हस्ताक्षर के एक भाग के रूप में NumberFormatException को निर्दिष्ट करना चाहिए।

मुझे ऐसा लगता है। यह एक अच्छा दस्तावेज है।

2. मुझे अपने स्वयं के जांचे गए अपवाद (BadDataException) को परिभाषित करना चाहिए, विधि के अंदर NumberFormatException को संभालना चाहिए और इसे BadDataException के रूप में फिर से फेंकना चाहिए।

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

3. मुझे अपने स्वयं के चेक किए गए अपवाद (BadDataException) को परिभाषित करना चाहिए, दोनों स्ट्रिंग्स को किसी तरह से नियमित अभिव्यक्तियों की तरह सत्यापित करें और अगर यह मेल नहीं खाता है तो मेरे BadDataException को फेंक दें।

कभी नहीँ। अधिक काम, कम गति (जब तक आप एक नियम होने के अपवाद को फेंकने की अपेक्षा नहीं करते हैं), और कोई लाभ नहीं।

4. आपका विचार?

बिलकुल भी नहीं।


2

Nr 4।

मुझे लगता है कि मैं इस विधि को बिल्कुल नहीं बदलूंगा। मैं कॉलिंग मेथड के आसपास या स्टैक-ट्रेस में उच्चतर कैच ट्राई करूंगा जहां मैं एक संदर्भ में हूं जहां मैं अपवाद से व्यापारिक तर्क के साथ शान से ठीक हो सकता हूं।

मैं निश्चित रूप से # 3 नहीं करूंगा क्योंकि मैं इसे ओवरकिल कर रहा हूं।


2

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


2
  1. सबसे पहले आपको अपने आप से पूछने की जरूरत है, क्या मेरी पद्धति के उपयोगकर्ता को गलत डेटा दर्ज करने के बारे में चिंता करने की आवश्यकता है, या क्या उससे उचित डेटा दर्ज करने की उम्मीद है (इस मामले में स्ट्रिंग)। इस अपेक्षा को अनुबंध द्वारा डिजाइन के रूप में भी जाना जाता है ।

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

  3. यह स्थिति पर निर्भर करता है बू मैं शायद कुछ अतिरिक्त जानकारी के साथ NumberFormatException को फिर से फेंक देगा। और इसके लिए एक जावाडॉक स्पष्टीकरण भी होना चाहिए कि इसके लिए अपेक्षित मूल्य क्या हैंString a, String b


1

आप जिस परिदृश्य में हैं उस पर बहुत कुछ निर्भर करता है।

केस 1. इसका हमेशा आप जो कोड को डीबग करते हैं और कोई और अपवाद नहीं है, एक खराब उपयोगकर्ता अनुभव का कारण बनता है

डिफ़ॉल्ट नंबर फेंक दो। अपवाद

Case2: कोड अत्यंत बनाए रखने योग्य और समझने योग्य होना चाहिए

अपने स्वयं के अपवाद को परिभाषित करें और इसे फेंकते समय डिबगिंग के लिए बहुत अधिक डेटा जोड़ें।

आप के रूप में regex जाँच की जरूरत नहीं है, इसके लिए वैसे भी खराब इनपुट पर अपवाद के लिए जाना जाता है।

यदि यह एक उत्पादन स्तर कोड था, तो मेरा विचार एक से अधिक कस्टम अपवादों को परिभाषित करना होगा, जैसे

  1. संख्या स्वरूप अपवाद
  2. अतिप्रवाह अपवाद
  3. अशक्त अपवाद आदि ...

और इन सभी से अलग तरीके से निपटें


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

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


1

प्रलेखन में किसी भी असाधारण व्यवहार को स्पष्ट किया जाना चाहिए। या तो यह बताना चाहिए कि यह विधि विफलता के मामले में एक विशेष मूल्य लौटाती है (जैसे null, रिटर्न प्रकार बदलकर Integer) या केस 1 का उपयोग किया जाना चाहिए। विधि के हस्ताक्षर में यह स्पष्ट होने से उपयोगकर्ता इसे अनदेखा कर देता है यदि वह अन्य तरीकों से सही तार सुनिश्चित करता है, लेकिन यह अभी भी स्पष्ट है कि विधि इस तरह की विफलता को स्वयं से संभालती नहीं है।


1

अपने अद्यतन प्रश्न का उत्तर दें।

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

e.g ArrayIndexOutofBound

प्रत्येक लूप के लिए एक सामान्य आश्चर्य अपवाद भी।

ConcurrentModificationException or something like that

1

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

प्रश्न के अद्यतन के बारे में "कल्पना करें, यह एक ओपन-सोर्स फ्रेमवर्क नहीं है, जिसे आपको किसी कारण से उपयोग करना चाहिए। आप विधि के हस्ताक्षर को देखते हैं और सोचते हैं -" ठीक है, यह कभी नहीं फेंकता "। फिर, किसी दिन, आपको एक अपवाद मिला। । क्या यह सामान्य है?" आपकी विधि के javadoc को हमेशा आपके तरीके (पूर्व और बाद की बाधाओं) के व्यवहार को बाहर करना चाहिए। यह कहें कि कलेक्शन इंटरफेस की तर्ज पर सोचें जहां अगर एक शून्य की अनुमति नहीं है, तो javadoc का कहना है कि एक शून्य पॉइंटर अपवाद को फेंक दिया जाएगा, हालांकि यह विधि हस्ताक्षर का हिस्सा नहीं है।


2
NumberFormatException IllegalArgumentException का एक उपवर्ग है, इसलिए इस रैपिंग में कोई जानकारी नहीं है।
डॉन रॉबी

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

1

जैसा कि आप अच्छे जावा अभ्यास के बारे में बात कर रहे हैं, मेरी राय में यह हमेशा बेहतर होता है

  • अनियंत्रित अपवाद को संभालने के लिए और फिर एक अनियंत्रित अपवाद के माध्यम से इसका विश्लेषण करें।

  • कस्टम अनियंत्रित अपवाद को फेंकने के दौरान आप अपवाद संदेश जोड़ सकते हैं जिसे आपका ग्राहक समझ सकता है और मूल अपवाद के स्टैक ट्रेस को भी प्रिंट कर सकता है

  • कस्टम अपवाद को "फेंकता" घोषित करने की आवश्यकता नहीं है क्योंकि यह अनियंत्रित है।

  • इस तरह आप अनियंत्रित अपवादों के उपयोग का उल्लंघन नहीं कर रहे हैं, उसी समय कोड के ग्राहक आसानी से अपवाद के कारण और समाधान को समझ पाएंगे।

  • साथ ही जावा-डॉक में ठीक से प्रलेखित करना एक अच्छा अभ्यास है और इससे बहुत मदद मिलती है।


1

मुझे लगता है कि यह आपके उद्देश्य पर निर्भर करता है, लेकिन मैं इसे कम से कम दस्तावेज करूंगा:

/**
 * @return the sum (as an int) of the two strings
 * @throws NumberFormatException if either string can't be converted to an Integer
 */
public static int sum(String a, String b)
  int x = Integer.parseInt(a);
  int y = Integer.parseInt(b);
  return x + y;
}

या, java.lang.Integer वर्ग के लिए जावा स्रोत कोड से एक पृष्ठ लें:

public static int parseInt(java.lang.String string) throws java.lang.NumberFormatException;

1

Google की 'अमरूद' लाइब्रेरी या अपाचे की 'वैलिडेटर' लाइब्रेरी ( तुलना ) द्वारा लागू इनपुट सत्यापन पैटर्न के बारे में कैसे ?

मेरे अनुभव में, फ़ंक्शन की शुरुआत में फ़ंक्शन के मापदंडों को मान्य करने और अपवादों को फेंकने के लिए अच्छा व्यवहार माना जाता है जहां उपयुक्त हो।

इसके अलावा, मैं इस प्रश्न को काफी हद तक स्वतंत्र भाषा मानूंगा। यहां 'अच्छा अभ्यास' उन सभी भाषाओं पर लागू होगा जिनमें ऐसे कार्य हैं जो पैरामीटर ले सकते हैं जो मान्य हो सकते हैं या नहीं।


1

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

इस उदाहरण में, यदि कॉलिंग विधि दो स्ट्रिंग्स को एक इंट में परिवर्तित नहीं कर सकती है, तो यह कई चीजें कर सकती है। यह वास्तव में इस बात पर निर्भर करता है कि यह योग किस स्तर पर है। मैं मान रहा हूं कि स्ट्रिंग रूपांतरण फ्रंट-एंड कोड के बहुत करीब होगा (यदि यह ठीक से किया गया था), तो ऐसी स्थिति 1. सबसे अधिक संभावना होगी:

  1. एक त्रुटि संदेश सेट करें और प्रसंस्करण को रोक दें या एक त्रुटि पृष्ठ पर पुनर्निर्देशित करें
  2. झूठे लौटें (यानी, यह राशि को किसी अन्य वस्तु में डाल देगा और इसे वापस करने की आवश्यकता नहीं होगी)
  3. कुछ BadDataException को फेंक दें जैसा कि आप सुझाव दे रहे हैं, लेकिन जब तक इन दो नंबरों का योग बहुत महत्वपूर्ण नहीं है, यह ओवरकिल है, और जैसा कि ऊपर उल्लेख किया गया है, यह संभवतः बुरा डिज़ाइन है क्योंकि इसका अर्थ है कि रूपांतरण गलत जगह पर किया जा रहा है

1

इस सवाल के कई दिलचस्प जवाब हैं। लेकिन मैं अभी भी इसे जोड़ना चाहता हूं:

स्ट्रिंग पार्सिंग के लिए, मैं हमेशा "नियमित अभिव्यक्ति" का उपयोग करना पसंद करता हूं। Java.util.regex पैकेज हमारी सहायता के लिए है। इसलिए मैं कुछ इस तरह से समाप्त करूंगा, कि कभी भी कोई अपवाद नहीं होगा। यदि मैं कुछ त्रुटि पकड़ना चाहता हूं तो यह एक विशेष मूल्य वापस करने के लिए मेरे ऊपर है:

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public static int sum(String a, String b) {
  final String REGEX = "\\d"; // a single digit
  Pattern pattern = Pattern.compile(REGEX);
  Matcher matcher = pattern.matcher(a);
  if (matcher.find()) { x = Integer.matcher.group(); }
  Matcher matcher = pattern.matcher(b);
  if (matcher.find()) { y = Integer.matcher.group(); }
  return x + y;
}

जैसा कि एक देख सकता है, कोड अभी थोड़ा लंबा है, लेकिन हम संभाल सकते हैं कि हम क्या चाहते हैं (और x और y के लिए डिफ़ॉल्ट मान सेट करें, नियंत्रण करें कि अन्य क्लॉस, आदि के साथ क्या होता है ...) हम और भी सामान्य परिवर्तन लिख सकते हैं दिनचर्या, जिसके लिए हम स्ट्रिंग्स पास कर सकते हैं, डिफॉटल रिटर्न मान, कंपाइल करने के लिए REGEX कोड, फेंकने के लिए त्रुटि संदेश, ...

आशा है कि यह उपयोगी था।

चेतावनी: मैं इस कोड का परीक्षण करने में सक्षम नहीं था, इसलिए कृपया अंतिम सिंटैक्स समस्याओं का बहाना करें।


1
क्या हम जावा के बारे में बोल रहे हैं? क्या है Integer.matcher? privateचर विधि के अंदर? लापता (), भारतीय विदेश सेवा के लिए की बहुत सारी लापता ;, x, yघोषित नहीं किया, matcherदो बार की घोषणा की, ...
user85421

वास्तव में कार्लोस, मैंने इसे जल्दी में किया था, और जैसा कि मैंने कहा, तुरंत इसका परीक्षण करने में सक्षम नहीं था। माफ़ करना। मैं किस करने का रेगेक्स रास्ता दिखाना चाहता था।
लुई

ठीक है, लेकिन यह समस्या को हल नहीं करता है NumberFormatException - मुख्य प्रश्न IMO - (यह माना जाता है कि Integer.matcher.group()इसका मतलब है Integer.parseInt(matcher.group()))
user85421

0

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

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

तथ्य Integer.parseInt()ज्ञात है कि शब्दार्थ ज्ञात हैं - यह प्राथमिक उद्देश्य है कि यह वैध पूर्णांकों को पार्स करे । आपको एक स्पष्ट उपयोगकर्ता इनपुट सत्यापन / पार्सिंग चरण याद आ रहा है।

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