2010-05-21 26 views
9

एक संभावित कारण है क्योंकि एक NullPointerException एक रनटाइम अपवाद है क्योंकि हर विधि इसे फेंक सकती है, इसलिए प्रत्येक विधि को "NullPointerException फेंकता" होना चाहिए, और बदसूरत होगा। लेकिन यह रिमोटएक्सप्शन के साथ होता है।क्यों NullPointerException एक रनटाइम अपवाद है और RemoteException नहीं है?

और एक संभावित कारण है क्योंकि रिमोटएक्सप्शन रनटाइम अपवाद नहीं है, यह अपवाद का इलाज करने के लिए क्लाइंट को बताना है। लेकिन एक दूरस्थ वातावरण में हर विधि को फेंकता है, इसलिए NullPointerException फेंकने में कोई अंतर नहीं है।

अटकलें? क्या मैं साफ़ था?

+1

कैसे लोगों को भी है कि जांचे हुए अपवादों की अवधारणा नहीं है भाषा में करते हैं? आप क्या कर सकते हैं जिसे किसी अन्य भाषा में साफ नहीं किया जा सकता है? समस्या यह है कि विफलता मानदंड है कि यह महसूस करने के बजाय "असफलताओं" को एक विशेष मामला माना जाता है। इस तरह के लोग बड़े विशाल गोटो बयान जैसे अपवादों की जांच करते हैं। राज्य परीक्षण विधियों? टाइमआउट? Naaaaah। बिग विशाल गॉट्स * "अगर sh! टी प्रशंसक हिट" *। बहुत अधिक जावा विनिर्देश और यह निश्चित रूप से ** नहीं ** पूरे जावा समुदाय को रैली करता है (उदाहरण के लिए वसंत ढांचे के प्रति उनकी बड़ी नफरत है)। – SyntaxT3rr0r

+5

वेबिनेटर, लड़के ने एक बिल्कुल उचित सवाल पूछा। रान करने की कोई जरूरत नहीं है। – DJClayworth

उत्तर

17

मैं इस फैसले पर चर्चा नहीं करूंगा, मैं केवल एन वोलरथ (जो जावा आरएमआई के डिजाइन और कार्यान्वयन का नेतृत्व करता है) के फैसले की व्याख्या का उद्धरण देगा। यह (जनवरी से 1999 संदेश) RMI उपयोगकर्ताओं अभिलेखागार से इस message से निकाला जाता है:

RemoteException एक अपवाद और में अपवाद सूची दूरस्थ तरीकों की आवश्यकता होती है जांच कर ली है निर्णय अपने फेंकता खंड नहीं है एक धार्मिक निर्णय वितरित कंप्यूटिंग विश्वसनीय बनाने के तरीके पर आधारित है। यह प्रश्न हमारे उपयोगकर्ताओं की सूची में में प्रत्येक बार आता है। मेरे पास विस्तृत प्रतिक्रिया है कि मैंने पहले पोस्ट किया था। यहां यह है कि यदि आप रुचि रखते हैं। मुझे इसे आरएमआई-उपयोगकर्ता संग्रह में नहीं मिला, इसलिए मैंने इसे नीचे शामिल किया।

चियर्स,

- एन


मैं नहीं बल्कि एक RuntimeException से RemoteException एक जाँच की अपवाद बनाने के लिए तर्क को संबोधित करने, चाहते हैं।

1) नेटवर्क विश्वसनीय

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

आरएमआई केवल सीमित मामले को संभालने के लिए डिज़ाइन नहीं किया गया है जो पूरे नेटवर्क क्रैश होता है जब एक मशीन क्रैश हो जाती है। इस तरह के नेटवर्क को विश्वसनीय माना जाएगा, या तो सबकुछ ऊपर है या सब कुछ नीचे है - आंशिक विफलता नहीं है। आरएमआई को के लिए अधिक सामान्य श्रोताओं के लिए लक्षित किया गया है।

2) आरपीसी विफलता ग्राहक से छुपाया नहीं जा सकता

आंशिक विफलता की एक सच्चाई वितरित प्रोग्रामिंग है; ये विफलताओं को प्रोग्राम पर छिपाया नहीं जा सकता है। एक विफलता क्लाइंट में दिखाई देती है, भले ही अपवाद चेक या अनचेक अपवाद है, तो यह अभी भी दिखाई देता है। तो, इस तरह के विफलताओं को क्लाइंट को कैसे इंगित किया जाना चाहिए?

3) अपवाद अधिक मजबूत कार्यक्रमों

एक समय था जब ओक और जावा के जल्द से जल्द संस्करण जांचे हुए अपवादों नहीं था था बढ़ावा जाँच की। अपवाद हैंडलिंग सलाहकार था, और यह वहां एक असुरक्षित दुनिया था। यह हमारा समूह था (जिम वाल्डो और मुझे विशेष रूप से :-) कि ने अनुशंसा की कि संकलक द्वारा अपवाद हो। जिम अपने तर्कों में प्रेरक था, दुनिया के बारे में बता रहा है जहां मजबूत कोड शासनकाल होगा। कुछ विचार करने के बाद, जावा को अपवादों की जांच करने के लिए पुनः स्थापित किया गया था। के लिए केवल उन्हीं अपवाद जिन्हें कोई पुनर्प्राप्ति नहीं मिली थी या एप्लिकेशन त्रुटियों को प्रतिबिंबित नहीं किया जाएगा (उदा।, OutOfMemoryError, क्रमशः NullPointerException)। और दुनिया फिर से सुरक्षित थी।

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

4) RemoteException एक जाँच की अपवाद

ठीक है, तो ट्रैक पर वापस यहाँ होना चाहिए के लिए उपयोगी है। के बाद से एक RemoteException एक RPC कॉल में जीवन की एक सच्चाई है (देखें # 1, # 2) और जाँच की अपवाद सुरक्षित कोड लिखने के लिए आपको जबरदस्ती (# 3), हमने सोचा कि RemoteException बनाने एक जाँच अपवाद एक था अच्छा विचार। लेखन वितरित प्रोग्राम संकलक के बिना आपको अपवादों के साथ मदद करने के लिए पर्याप्त कठिन है।

तो, कुछ तर्क दे सकते हैं कि रिमोटएक्सप्शन आउटऑफमेमरी एरर की तरह है; यदि आपका रिमोट कॉल विफल रहता है तो आपके प्रोग्राम को मृत पर गिरना चाहिए। मैं इस बिंदु से असहमत हूं। हां, में कुछ मामलों में रिमोट अपवाद से कोई वसूली नहीं है; लेकिन यदि आप विश्वसनीय विश्वसनीय प्रोग्राम लिख रहे हैं, तो आपके क्लाइंट को विफलताओं को पकड़ने और उचित रूप से पुनः प्रयास करने की आवश्यकता है। शायद आपको सर्वर से संपर्क करने की आवश्यकता है, या सॉर्ट के लेन-देन को रोकना है। यदि रिमोटएक्सप्शन संभाल नहीं है, तो यह बढ़ जाएगा और आपके क्लाइंट (yuk) को क्रैश करेगा।

दूसरों ने कहा है कुछ दूरदराज के इंटरफेस है कि स्थानीय मामले में अपवाद के साथ सौदा करने के लिए दोनों को स्थानीय और दूरदराज के मामले मामले और ग्राहक में किया जाता है नहीं करना चाहिए था, देखते हैं कि इतना RemoteException नहीं करना चाहिए को फेंकने वाले खंड में होना चाहिए और हैंडलिंग करना अनिवार्य नहीं होना चाहिए। अब, अगर हम RemoteException छोड़ दूरस्थ इंटरफ़ेस की अनुमति दी तरीकों और एक "rmic" स्विच था स्टब्स कि एक अनियंत्रित RemoteException फेंक उत्पन्न करने के लिए, ग्राहकमामले में कोई विकल्प है। अपवाद संचालन के निर्णय ग्राहक के साथ रहना चाहिए। आप एक इंटरफेस कि केवल अनियंत्रित अपवाद आप एक ग्राहक है कि उन अपवादों से निपटने में संकलक मदद चाहता है कभी नहीं लिख सकते हैं फेंकता है निर्धारित करते हैं। हम पहले से ही ऊपर के उदाहरण से देखा है कि जांचे हुए अपवादों को बढ़ावा मजबूत कोड।

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

हर में RemoteException लाना फेंकता खंड एक दर्द, लेकिन इसकी कीमत मजबूत वितरित अनुप्रयोगों के लेखन के लिए भुगतान करने के लिए की तरह लग सकता।

- एन Wollrath

+1

वह बहुत आश्वस्त दिखती है कि लोगों ने उन भाषाओं में "मजबूत वितरित अनुप्रयोग" [एसआईसी] नहीं लिखा है जिनके पास चेक अपवादों की अवधारणा भी नहीं है। मैं पिछली शताब्दी में धूम्रपान करने वाली चीज़ों का थोड़ा सा हिस्सा लेना चाहता हूं, मजबूत लगता है :) – SyntaxT3rr0r

+7

@ डाउनवॉटर I ** वास्तव में ** आश्चर्य है कि यह जवाब क्यों कम किया गया है। भले ही आप लेखक से असहमत हों, मैं ** संदर्भ ** पोस्ट कर रहा हूं, राय नहीं। भावनात्मक डाउनवॉट हास्यास्पद हैं। –

+1

मैं कल्पना नहीं कर सकता कि किसी ने भी चेक अपवादों पर किसी की भावनाओं के बावजूद यह क्यों कम किया होगा, यह स्पष्ट रूप से संभवत: आपके द्वारा प्राप्त किए जा सकने वाले प्रश्न का सबसे सही उत्तर है। – ColinD

4

RemoteException से NullPointerException के लिए बहुत अधिक संभावना है। कोई भी कोड जो ऑब्जेक्ट पर किसी विधि को कॉल करता है (जिसका अर्थ है व्यावहारिक रूप से कोई भी जावा कोड) संभावित रूप से NullPointerException फेंक सकता है। केवल आरएमआई कोड RemoteException फेंक सकता है। यह "सभी कोड" का एक छोटा सबसेट है।

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

0

RemoteException इसके अलावा केवल java.rmi और javax.rmi पैकेज (और उनके सबपैकेज) से कोड को लागू करने से, RemoteException, IOException का एक प्रकार है SocketException है बहुत पसंद है ... और सभी IOException की अपवाद जाँच कर रहे हैं।

+0

मैं आपको कम नहीं करूँगा, लेकिन यह उत्तर एक रनटाइम अपवाद नहीं होने का एक संभावित कारण नहीं है। IOExeption के बजाय RemoteException केवल अपवाद का एक प्रकार हो सकता है। अपवाद जांचने का निर्णय लेने के बाद एक IOException एक निर्णय बनें। –

+0

संचार में काम करने वाले जावा में सभी अपवाद 'IOException' के उप-वर्ग हैं। 'IOException' (और किसी भी अन्य वर्ग जो' RuntimeException' की बजाय 'अपवाद' से प्राप्त होता है) एक चेक अपवाद है, इस प्रकार से प्राप्त होने वाले किसी वर्ग को भी अपवादों की जांच की जाती है। – Powerlord

2

तरह से मैं इसे समझ है:

  • RuntimeExceptions चीजें हैं जो रोके थे के लिए फेंक दिया जाता है।
  • अपरिवर्तनीय चीजों के लिए अपवादों को फेंक दिया गया है लेकिन पुनर्प्राप्ति योग्य
  • उन चीजों के लिए त्रुटियां फेंक दी गई हैं जो अपरिवर्तनीय और अप्राप्य थीं।

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

+1

मुझे लगता है कि आपने अपनी सूची में "अपवाद" और "रनटाइम अपवाद" को उलट दिया है। 'NullPointerException' एक 'RuntimeException' है। – Matthew

+0

आह, हाँ! धन्यवाद – Steve

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