Java को Serializable इंटरफ़ेस की आवश्यकता क्यों है?


114

हम क्रमबद्धता के साथ बहुत अधिक काम करते हैं और हमारे द्वारा उपयोग की जाने वाली प्रत्येक वस्तु पर अनुक्रमिक टैग निर्दिष्ट करना एक तरह का बोझ है। खासकर जब यह एक 3-पार्टी वर्ग है जिसे हम वास्तव में बदल नहीं सकते हैं।

सवाल यह है: चूंकि सीरियल एक खाली इंटरफ़ेस है और जब आप जोड़ते हैं तो जावा एक मजबूत क्रमांकन प्रदान करता है implements Serializable- उन्होंने सब कुछ सीरियल करने योग्य क्यों नहीं बनाया?

मैं क्या खो रहा हूँ?


क्या होगा यदि आप अपनी खुद की वस्तु को सीरियल बनाने योग्य बनाना चाहते हैं? या मैंने कुछ गलत समझा?
जो फिलिप्स

मुझे अभी भी NotSerializableException मिल जाएगी क्योंकि मेरी वस्तुओं के सभी क्षेत्रों को क्रमिक होना होगा
Yoni Roit

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

जवाबों:


120

सीरियलाइजेशन नुकसान के साथ भरा हुआ है। इस फॉर्म का स्वचालित क्रमांकन समर्थन सार्वजनिक इंटरनैशनल का हिस्सा बनाता है (यही कारण है कि javadoc आपको कक्षाओं के स्थायी रूप देता है )।

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

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

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

सभी वर्गों को क्रमबद्ध बनाना इन समस्याओं को बढ़ा देगा। की जाँच करें प्रभावी जावा द्वितीय संस्करण , विशेष रूप से आइटम 74: विवेकपूर्ण तरीके से लागू Serializable


2
यह स्पष्ट रूप से बेहतर उत्तर है, मैं निराश हूं कि चयनित उत्तर यह नहीं है, ऐसा लगता है कि पोस्ट को "इम नाराज़ के साथ चुना गया है क्योंकि मुझे चीजों को क्रमबद्ध करने की घोषणा करनी है" मन में एजेंडा। इसके कुछ उदाहरणों में से एक ऐसा है जो घर-घर जाकर पहले से सीखे गए सुरक्षा और डिजाइन सबक को ध्यान में नहीं रखना चाहता है।
१:30:३० पर gbtimmon

@McDowell कक्षाओं के निरंतर रूप से आपका क्या मतलब है? मैंने उस लिंक का अनुसरण किया लेकिन समझ नहीं पाया कि आपका क्या मतलब है? क्या आप इसे समझा सकते हैं?
Geek

@ गीक - URL प्रकार का क्रमबद्ध रूप (उदाहरण के लिए) यह परिभाषित करता है कि किस निजी क्षेत्र का प्रकार होना चाहिए और उन्हें किस क्रम में घोषित किया जाना चाहिए।
मैकडोवेल

@McDowell ऑर्डर क्यों मायने रखता है?
Geek

12
@McDowell हाय। मैं 4 साल पहले से इस सवाल का मूल पोस्टर हूं, और मैंने आपके उत्तर को स्वीकार के रूप में चुना है, अगर इसका कोई मतलब है। मुझे लगता है कि आपका उत्तर वास्तव में बेहतर है, और मैं शायद उस समय इसे देखने के लिए बहुत अपरिपक्व था। अब ठीक हो रहा है :)
योनी रोत

32

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

उदाहरण के लिए Smalltalk (70 के दशक में बनाई गई भाषा) में प्रत्येक वस्तु डिफ़ॉल्ट रूप से क्रमबद्ध होती है। मुझे नहीं पता कि यह जावा में ऐसा क्यों नहीं है, इस तथ्य पर विचार करते हुए कि वस्तुओं का विशाल बहुमत क्रमबद्ध करने के लिए सुरक्षित है और उनमें से कुछ ही नहीं हैं।

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

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


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

@ रॉल्फ रैंडर: ज्यादातर समय आपको किसी भी तरह की देखभाल करने की आवश्यकता नहीं होती है, बस कक्षा को क्रमबद्ध करने के लिए चिह्नित करें। यदि धारावाहिकीकरण सभी वस्तुओं पर डिफॉल के द्वारा किया गया होता, तो हर डेवलपर की मानसिकता भी भिन्न होती, कक्षा क्रमिक बनाने के लिए ऐसा करना कुछ स्वाभाविक होता ...
पॉप कैटालिन

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

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

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

20

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


यह मेरी समस्या होगी और अगर मैं सॉकेट को क्रमबद्ध करने की कोशिश करने के लिए पर्याप्त स्मार्ट नहीं था, तो मुझे डिबगिंग के दौरान अपनी त्रुटि मिलेगी। हालाँकि, अब मैं ऐसी स्थिति में हूँ, जब मैं 3rd पार्टी क्लास के कारण जावा सीरियलाइज़ेशन का उपयोग नहीं कर सकता, जो बिना किसी अच्छे कारण के Serializable को लागू नहीं करता है।
योनी रोहित

4
इस मामले को संभालने के लिए कुछ अच्छे तरीके हैं, जैसे कि एक Serializable आवरण वर्ग लिखना जो 3 पार्टी पार्टी के प्रमुख डेटा को पढ़ना और लिखना जानता है; लिपटे उदाहरण क्षणिक बनाने के लिए और लिखने से बाहर निकलें और पढ़ने से हटा दें।
ग्रेग केस

क्या आप अपने एपीआई में आवश्यक वस्तुओं से वारिस कर सकते हैं और उन वर्गों को क्रमबद्ध कर सकते हैं?
जोएल कोएहॉर्न

@Joel: यह एक अच्छा विचार है, लेकिन अभी भी एक हैक है। मुझे लगता है कि यह पूरी बात सिर्फ एक और व्यापार गलत हो गया है। आपकी टिप्पणियों के लिए आभार।
योनी रोहित

1
यह उन दुर्लभ उदाहरणों में से एक है जो दिखाता है कि हम सभी की वास्तव में आवश्यकता है implements NotSerializable:)
रोब ग्रांट

13

Java में Serializable की मुख्य भूमिका वास्तव में बनाने के लिए है, डिफ़ॉल्ट रूप से, अन्य सभी ऑब्जेक्ट्स nonserializable। सीरियलाइज़ेशन एक बहुत ही खतरनाक तंत्र है, खासकर इसके डिफ़ॉल्ट कार्यान्वयन में। इसलिए, सी ++ में दोस्ती की तरह, यह डिफ़ॉल्ट रूप से बंद है, भले ही चीजों को धारावाहिक बनाने के लिए थोड़ा खर्च होता है।

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

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


9

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

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


4

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


3

जाहिर तौर पर कुछ प्रारंभिक डिजाइनों में सब कुछ क्रमिक था, लेकिन सुरक्षा और शुद्धता की चिंताओं के कारण अंतिम डिजाइन समाप्त हो गया जैसा कि हम सभी जानते हैं।

स्रोत: ObjectOutputStream को लिखने के लिए कक्षाओं को क्रमिक रूप से लागू क्यों करना चाहिए?


1

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

सिर्फ जेवीएम के मानक क्रमांकन समर्थन पर भरोसा करके आप अपने आप को सभी प्रकार के खराब संस्करण के मुद्दों से उजागर करते हैं।

विशिष्टता, 'वास्तविक' संसाधनों, टाइमर और अन्य प्रकार की कलाकृतियों के संदर्भ में क्रमिकता के लिए उम्मीदवार नहीं हैं।


1

Serializable Interface को समझने के लिए इसे पढ़ें और हमें केवल कुछ वर्गों को Serializable क्यों बनाना चाहिए और साथ ही यह भी ध्यान रखना चाहिए कि जहाँ हम कुछ फ़ील्ड्स को स्टोर करने की प्रक्रिया से निकालना चाहते हैं, वहाँ transient कीवर्ड का उपयोग करें।

http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/


0

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

तो, आपको मूल रूप से क्या करने की आवश्यकता है, अपने 3-पार्टी वर्ग के सभी गुणों को स्वयं पढ़ें। या, यदि यह आपके लिए एक विकल्प है: विघटित, वहाँ लानत कीवर्ड डाल दिया, और recompile।


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

मुझे यकीन नहीं है कि आप "संरचना संगतता" से क्या मतलब है।
nes1983

0

जावा में कुछ चीजें हैं जो केवल क्रमबद्ध नहीं हो सकती हैं क्योंकि वे रनटाइम विशिष्ट हैं। स्ट्रीम, थ्रेड, रनटाइम, आदि और यहां तक ​​कि कुछ GUI कक्षाएं (जो अंतर्निहित OS से जुड़ी हैं) जैसी चीजों को क्रमबद्ध नहीं किया जा सकता है।


0

जब मैं यहां अन्य उत्तरों में किए गए बिंदुओं से सहमत हूं, तो असली समस्या डिसेरिअलाइज़ेशन के साथ है: यदि कक्षा की परिभाषा बदल जाती है, तो एक वास्तविक जोखिम है कि डीरिशियलेशन काम नहीं करेगा। पुस्तकालय बनाने के लेखक के लिए मौजूदा फ़ील्ड को कभी भी संशोधित करना एक बहुत बड़ी प्रतिबद्धता नहीं है! एपीआई संगतता को बनाए रखना एक राग के रूप में पर्याप्त है।


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

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

0

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

ऑब्जेक्ट क्लास में डिफ़ॉल्ट रूप से ऑब्जेक्ट क्लास सीरियल करने योग्य नहीं है इसका कारण यह है कि क्लास संस्करण प्रमुख मुद्दा है। इसलिए प्रत्येक श्रेणी जिसे क्रमांकन में रुचि है, को स्पष्ट रूप से सीरियल के रूप में चिह्नित किया जाना है और एक संस्करण संख्या प्रदान करना है सीरियलवीडियोयूआईडी।

यदि serialVersionUID प्रदान नहीं किया गया है, तो हमें ऑब्जेक्ट को डिस्क्राइब करने के दौरान अप्रत्याशित परिणाम प्राप्त होते हैं, यही कारण है कि यदि सीरियलVersionUID मेल नहीं खाता है, तो JVM InvalidClassException को फेंकता है । इसलिए हर वर्ग को Serializable इंटरफ़ेस लागू करना है और यह सुनिश्चित करने के लिए serialVersionUID प्रदान करना है कि दोनों सिरों पर प्रस्तुत वर्ग समान है।

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