2011-09-16 9 views
20

मैं "प्रभावी जावा" में क्रमबद्धता अध्याय पढ़ रहा हूं। मैं पुस्तक में नीचे दिए गए अनुच्छेद को समझने की कोशिश कर रहा हूं।जावा: serialization के दौरान readObjectNoData() को कब जोड़ना है?

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

// readObjectNoData for stateful extendable serializable classes 
    private void readObjectNoData() throws InvalidObjectException { 
      throw new InvalidObjectException("Stream data required"); 
    } 

मुझे यकीन है कि क्या इसके बाद के संस्करण बयान का मतलब है नहीं कर रहा हूँ।

इस परीक्षण के लिए, मैं एक वर्ग व्यक्ति (दोनों serializable और बढ़ाई)

class Person implements Serializable{ 

     private String name; 

     private int age; 

     Person() { 
     this("default",1); 
     } 


    Person(String name, int y) { 
     this.name = name; 
     this.age = y; 
     } 
    } 

और एक वर्ग के कर्मचारी जो यह फैली बनाया।

 class Employee extends Person { 

     String address ; 


    public Employee() 
    { 
     super(); 
     address ="default_address"; 
    } 

    public Employee(String name , int age, String address) 
    { 
     super(name,age); 
     this.address = address; 
    } 
      } 

क्या मैंने बनाए गए व्यक्ति वर्ग में कोई आविष्कार किया है? उनका उल्लंघन कब किया जाएगा? मैंने कर्मचारी वर्ग में readObjectData() विधि के लिए कोड चिपकाया, लेकिन इसे कभी नहीं बुलाया गया। विधि कब ऑब्जेक्ट() को बुलाया जाएगा? क्या मैं कुछ भूल रहा हूँ ?

+0

आपकी कक्षा 'कर्मचारी' में 'व्यक्ति' (इस उदाहरण के प्रयोजन के लिए) शामिल नहीं होना चाहिए, लेकिन व्यक्ति का उप-वर्ग होना चाहिए, यानी 'इसे बढ़ाता है'। – Barend

+0

कोड संपादित किया गया। – vinoth

उत्तर

21

readObjectNoData section जावा ऑब्जेक्ट क्रमबद्धता विशिष्टता में दिलचस्प लगता है (नीचे देखें)।

प्रश्न के आपके संपादन एक आदर्श उदाहरण देते हैं। यदि Employeeserialized था जब यह Person और बाद में deserialized का विस्तार नहीं किया गया तो Person भाग खाली स्ट्रिंग और 0 आयु के लिए प्रारंभ किया जाएगा। इस विधि का उपयोग करके, आप उन्हें क्रमशः "नाम" और 1 में प्रारंभ कर सकते हैं।

serializable वस्तुओं के लिए, readObjectNoData विधि घटना में अपने स्वयं के क्षेत्रों में से प्रारंभ नियंत्रित करने के लिए है कि एक उपवर्ग उदाहरण deserialized है एक वर्ग अनुमति देता है और क्रमबद्धता धारा एक सुपर क्लास के रूप में प्रश्न में वर्ग की सूची नहीं है deserialized वस्तु का। यह उन मामलों में हो सकता है जहां प्राप्तकर्ता पार्टी भेजने से deserialized इंस्टेंस की कक्षा के विभिन्न संस्करण का उपयोग करती है, और रिसीवर का संस्करण उन कक्षाओं को बढ़ाता है जो प्रेषक के संस्करण द्वारा विस्तारित नहीं हैं।यह तब भी हो सकता है जब धारावाहिक धारा छेड़छाड़ की गई है; इसलिए, readObjectNoData "शत्रुतापूर्ण" या अपूर्ण स्रोत स्ट्रीम के बावजूद deserialized वस्तुओं को ठीक से शुरू करने के लिए उपयोगी है।

private void readObjectNoData() throws ObjectStreamException;

प्रत्येक serializable वर्ग का अपना readObjectNoData विधि परिभाषित कर सकते हैं। यदि एक धारावाहिक वर्ग एक readObjectNoData विधि को परिभाषित नहीं करता है, तो कक्षा के क्षेत्रों के ऊपर सूचीबद्ध परिस्थितियों में उनके डिफ़ॉल्ट मानों के लिए आरंभ किया जाएगा (जैसा कि जावाटीएम भाषा विशिष्टता, द्वितीय संस्करण की धारा 4.5.5 में सूचीबद्ध है) ; जावाटीएम 2 एसडीके, मानक संस्करण के संस्करण 1.4 से पहले ऑब्जेक्टइनपूटस्ट्रीम के साथ संगत है, जब readObjectNoData विधियों के लिए समर्थन प्रस्तुत किया गया था। यदि एक धारावाहिक वर्ग readObjectNoData विधि को परिभाषित करता है और उपर्युक्त स्थितियां उत्पन्न होती हैं, तो readObjectNoData को deserialization के दौरान बिंदु पर बुलाया जाएगा जब कक्षा-परिभाषित readObject विधि को अन्यथा बुलाया जाएगा कक्षा में प्रश्न के अनुसार सूचीबद्ध किया गया था उदाहरण के सुपरक्लास के रूप में deserialized किया जा रहा है।

+0

वास्तव में प्रश्न का उत्तर देने के लिए प्रतीत नहीं होता है। उदाहरण के लिए, readObjectNoData को सिंगलटन एनम में आवश्यक है जो सीरियलज़ेबल लंबे समय से एनमम होने से अधिक है? – user833771

+0

@ user833771 यह एक दिलचस्प सवाल है, लेकिन यह मूल प्रश्न के प्रतिबंध में फिट नहीं है, एक वर्ग जो धारावाहिक और विस्तार योग्य है क्योंकि एनम को विरासत में नहीं मिला है। –

+0

मेरा मतलब है कि एक enum जो पहले एक सामान्य वर्ग Serializable लागू करने वाला था। – user833771

0

एक अपरिवर्तनीय अपने व्यक्ति वर्ग में हो सकता है कुछ की तरह:

age must be greater than 0 

तो, जब व्यक्ति वर्ग डिफ़ॉल्ट मान, 0 के साथ instantiated है (यहाँ देखें: http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) आपको लगता है कि अपरिवर्तनीय का उल्लंघन किया है जाएगा।

हालांकि, डिफ़ॉल्ट निर्माता आप ठीक हो जाएगा दिया :)

+0

ठीक है मेरे पास एक डिफ़ॉल्ट कन्स्ट्रक्टर है जो सुनिश्चित करता है कि आयु> 0. readObjectData() कहां खेलता है? – vinoth

3

वहाँ व्यक्ति वर्ग में किसी भी अपरिवर्तनशीलताओं मेरे द्वारा बनाए गए हैं? उनका उल्लंघन कब किया जाएगा?

कोई भी स्पष्ट रूप से है, लेकिन कल्पना कक्षा में अन्य तरीकों को लगता है कि कि namenull कभी नहीं है और NullPointerException फेंक अगर यह कभी होने पर होता। इस मामले में, name की गैर-शून्यता एक आविष्कार है।

मैं Employee कक्षा में readObjectData() विधि के लिए कोड की नकल की है, लेकिन यह कभी नहीं कहा जाता हो गया। विधि readObject() कब कॉल की जाएगी?

कोई विधि नहीं है readObjectData() क्रमबद्धता के साथ शामिल है, यह एक टाइपो होना चाहिए। readObject() विधि हर बार एक धारावाहिक वस्तु deserialized कहा जाता है।

readObjectNoData() विधि कुछ अस्पष्ट कोने के मामले के लिए हिट होती है जब उप-वर्ग उस विधि के वर्ग में deserializing।

सूर्य ओरेकल वेबसाइट पर advanced serialization लेख इन क्रमबद्धता सहायक तरीकों के प्रयोजन को शामिल किया गया। मेरा सुझाव है कि आप वहां से शुरू करें और बाद में जिन प्रश्नों को आप चला सकते हैं पोस्ट करें।

(अद्यतन)

आप उत्सुक हैं मामले में, readObjectNoData विधि रिलीज 1.4 में जोड़ा गया है किसी मौजूदा serializable वर्ग के लिए एक serializable सुपर क्लास के अलावा शामिल एक कोने मामले को कवर किया। विवरण serialization विनिर्देश Serialization, 3.5 में पाया जा सकता है।

संदर्भित पाठ है:

serializable वस्तुओं के लिए, readObjectNoData विधि एक वर्ग स्पर्धा में अपने स्वयं के क्षेत्रों में से प्रारंभ नियंत्रित करने के लिए है कि एक उपवर्ग उदाहरण deserialized है की अनुमति देता है और क्रमबद्धता धारा नहीं है deserialized वस्तु के एक superclass के रूप में सवाल वर्ग में सूची। यह उन मामलों में हो सकता है जहां प्राप्तकर्ता पार्टी भेजने वाली पार्टी की तुलना में deserialized इंस्टेंस की कक्षा के एक अलग संस्करण का उपयोग करती है, और रिसीवर का संस्करण कक्षाओं को बढ़ाता है जो प्रेषक के संस्करण द्वारा विस्तारित नहीं होते हैं। यह तब भी हो सकता है जब धारावाहिक धारा छेड़छाड़ की गई हो; इसलिए, readObjectNoData "शत्रुतापूर्ण" या अपूर्ण स्रोत स्ट्रीम के बावजूद deserialized वस्तुओं को ठीक से शुरू करने के लिए उपयोगी है।

तो यह दो मामलों में हो सकता है:

  • JVM डीकोड उस वस्तु धारा deserialized जा रहा है एक नए उपवर्ग के संस्करण (Employee), एक है कि कुछ माता पिता वर्ग (Person) फैली हुई है। जेवीएम जो मूल रूप से * एन * ऑब्जेक्ट स्ट्रीम को कोड करता है, इन वर्गों का एक अलग, पुराना संस्करण है, जहां Person अभी तक Employee का सुपरक्लास नहीं था।
  • किसी ने चीजों को तोड़ने के लिए जानबूझकर ऑब्जेक्ट स्ट्रीम के साथ गड़बड़ की।
3

"विस्तार योग्य" का अर्थ है "उप-वर्ग हो सकता है"।

readObjectNoData जबकि वर्ग के deserializer (पाठक) एक पर आधारित है कि वर्ग के एक संस्करण है एक असामान्य मामले में जहां serializer (लेखक) कोई आधार वर्ग के साथ एक वर्ग का एक संस्करण के साथ काम कर रहा है में प्रयोग किया जाता है, उपवर्ग। सबक्लास कह सकता है, "ठीक है अगर मेरी बेस क्लास धारावाहिक डेटा में नहीं है - readObjectNoData को लागू करके बस एक खाली करें"। इन release notes देखें।

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