2010-08-07 25 views
87

जावा में Serializable होने के लिए कक्षा का क्या अर्थ है? या सामान्य रूप से, उस मामले के लिए ...सीरियलज़ेबल का क्या अर्थ है?

+10

@skaffman क्लास 'Serializable': के लिए यह कहता है कि क्लास की Serializability java.io.Serializable इंटरफ़ेस को लागू करने वाले वर्ग द्वारा सक्षम किया गया है। कक्षाएं जो इस इंटरफ़ेस को लागू नहीं करती हैं, उनमें से कोई भी राज्य क्रमबद्ध या deserialized नहीं होगा। एक serializable वर्ग के सभी उपप्रकार स्वयं serializable हैं। सीरियलाइजेशन इंटरफ़ेस में कोई तरीका या फ़ील्ड नहीं है और केवल सीरियलज़ेबल होने के अर्थशास्त्र की पहचान करने के लिए कार्य करता है। –

+26

यदि आप पहले ही जानते हैं कि धारावाहिक और deserialized मतलब क्या है एक महान स्पष्टीकरण। (तारीफ नहीं।) ऐसी परिभाषाएं आपको इस मुद्दे को बेहतर तकनीकी रूप से समझने में मदद करती हैं, और केवल एक बार, आपके पास पहले से ही कुछ ज्ञान है। – Xonatron

उत्तर

92

Serialization डिस्क पर सहेजने के लिए स्मृति से ऑब्जेक्ट से बिट्स के अनुक्रम तक एक वस्तु को जारी रखता है। Deserialization विपरीत है - डिस्क से हाइड्रेट/ऑब्जेक्ट बनाने के लिए डेटा पढ़ने।

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

+1

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

29

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

5

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

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

+4

यह 'कंपाइलर के लिए ध्वज' नहीं है। यह रनटाइम पर, सीरियलाइजेशन उपप्रणाली का ध्वज है। – EJP

+0

@EJP - धन्यवाद, यह नहीं पता था कि – AphexMunky

+0

सम्मान के साथ, जब आप इसे सत्य नहीं जानते हैं तो इसे क्यों लिखें? आपने 'क्षणिक' भी छोड़ा है। सब कुछ एक गरीब जवाब में, क्षमा करें। – EJP

8

सीरियलाइजेशन में किसी ऑब्जेक्ट की वर्तमान स्थिति को स्ट्रीम में सहेजना और उस स्ट्रीम से समकक्ष ऑब्जेक्ट को पुनर्स्थापित करना शामिल है। धारा

0

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

4

सीरियलाइजेशन फाइलों में ऑब्जेक्ट्स और डेटा को संग्रहीत करने या लिखने की तकनीक है। ObjectOutputStream और FileOutputStream कक्षाओं का उपयोग करके। इन वर्गों में वस्तुओं को बनाए रखने के लिए उनके विशिष्ट तरीके हैं। जैसे writeObject();

आंकड़ों के साथ स्पष्ट स्पष्टीकरण के लिए। See Here for more info

1

किसी अन्य परिप्रेक्ष्य से प्रस्तुत करने के लिए। सीरियलाइजेशन 'मार्कर इंटरफ़ेस' नामक इंटरफ़ेस का एक प्रकार है। एक मार्कर इंटरफ़ेस एक इंटरफ़ेस होता है जिसमें कोई विधि घोषणा नहीं होती है, लेकिन केवल उस श्रेणी को निर्दिष्ट करता है (या "अंक") जो इंटरफ़ेस को कुछ संपत्ति के रूप में लागू करता है। यदि आप बहुरूपता को समझते हैं तो यह बहुत अधिक समझ में आता है। Serializable मार्कर इंटरफ़ेस के मामले में, ऑब्जेक्टऑटपुटस्ट्रीम.write (ऑब्जेक्ट) विधि विफल हो जाएगी यदि इसका तर्क इंटरफ़ेस को लागू नहीं करता है। यह जावा में एक संभावित गलती है, यह ObjectOutputStream.write (Serializable)

हो सकता था पुरज़ोर सलाह दी जाती: प्रभावी जावा से आइटम 37 पढ़ना यहोशू बलोच से अधिक जानने के लिए।

27

हालांकि उपयोगकर्ताओं के अधिकांश पहले से ही इस सवाल का जवाब दे दिया है, लेकिन मैं जो लोग इसे क्रम में की जरूरत के लिए एक उदाहरण जोड़ने के लिए विचार की व्याख्या करना चाहते हैं:

मान लीजिए कि आप निम्नलिखित की तरह एक वर्ग व्यक्ति करते हैं:

public class Person implements java.io.Serializable { 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    public String firstName; 
    public String lastName; 
    public int age; 
    public String address; 

    public void play() { 
     System.out.println(String.format(
       "If I win, send me the trophy to this address: %s", address)); 
    } 
    @Override 
    public String toString() { 
     return String.format(".....Person......\nFirst Name = %s\nLast Name = %s", firstName, lastName); 
    } 
} 

और उसके बाद आप इस तरह एक वस्तु बनाने के लिए:

Person william = new Person(); 
     william.firstName = "William"; 
     william.lastName = "Kinaan"; 
     william.age = 26; 
     william.address = "Lisbon, Portugal"; 

आप कई धाराओं को उस वस्तु serialise कर सकते हैं। मैं दो धाराओं है कि क्या करेंगे:

public static void serializeToFile(Person person) throws IOException { 
     OutputStream outStream = new FileOutputStream("person.ser"); 
     ObjectOutputStream fileObjectOut = new ObjectOutputStream(outStream); 
     fileObjectOut.writeObject(person); 
     fileObjectOut.close(); 
     outStream.close(); 
    } 

तब:

deserialize फ़ाइल से

public static void serializeToStandardOutput(Person person) 
      throws IOException { 
     OutputStream outStream = System.out; 
     ObjectOutputStream stdObjectOut = new ObjectOutputStream(outStream); 
     stdObjectOut.writeObject(person); 
     stdObjectOut.close(); 
     outStream.close(); 
    } 

क्रमबद्धता एक फाइल करने के लिए:

क्रमबद्धता मानक आउटपुट में :

public static void deserializeFromFile() throws IOException, 
      ClassNotFoundException { 
     InputStream inStream = new FileInputStream("person.ser"); 
     ObjectInputStream fileObjectIn = new ObjectInputStream(inStream); 
     Person person = (Person) fileObjectIn.readObject(); 
     System.out.println(person); 
     fileObjectIn.close(); 
     inStream.close(); 
    } 
1

क्रमबद्धता: ऑब्जेक्ट की लेखन राज्य फ़ाइल/नेटवर्क या कहीं भी। (समर्थित जावा ऑब्जेक्ट समर्थित फॉर्म फ़ाइल समर्थित फॉर्म या नेटवर्क समर्थित फॉर्म)

Deserialization: फ़ाइल/नेटवर्क या कहीं से भी ऑब्जेक्ट स्टेटस पढ़ना। (मतलब जावा ऑब्जेक्ट समर्थित फार्म करने के लिए फ़ाइल/नेटवर्क समर्थित प्रपत्र)

4

Here is a detailed explanation of the Serialization: (मेरे अपने ब्लॉग)

क्रमबद्धता:

क्रमबद्धता है एक वस्तु का राज्य serializing की प्रक्रिया का प्रतिनिधित्व करती है और बाइट्स के अनुक्रम के रूप में संग्रहीत। यह एक फाइल में संग्रहीत किया जा सकता है। फ़ाइल से ऑब्जेक्ट की स्थिति को पढ़ने और इसे बहाल करने की प्रक्रिया को deserialization कहा जाता है।

सीरियलाइजेशन की आवश्यकता क्या है?

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

कोड उदाहरण और स्पष्टीकरण:

पहले के मद कक्षा पर एक नज़र डालते हैं:

public class Item implements Serializable{ 

    /** 
    * This is the Serializable class 
    */ 
    private static final long serialVersionUID = 475918891428093041L; 
    private Long itemId; 
    private String itemName; 
    private transient Double itemCostPrice; 
    public Item(Long itemId, String itemName, Double itemCostPrice) { 
     super(); 
     this.itemId = itemId; 
     this.itemName = itemName; 
     this.itemCostPrice = itemCostPrice; 
     } 

     public Long getItemId() { 
      return itemId; 
     } 

    @Override 
     public String toString() { 
      return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]"; 
     } 


     public void setItemId(Long itemId) { 
      this.itemId = itemId; 
     } 

     public String getItemName() { 
      return itemName; 
     } 
     public void setItemName(String itemName) { 
      this.itemName = itemName; 
     } 

     public Double getItemCostPrice() { 
      return itemCostPrice; 
     } 

     public void setItemCostPrice(Double itemCostPrice) { 
      this.itemCostPrice = itemCostPrice; 
     } 
} 

ऊपर कोड यह देखा जा सकता है कि आइटम वर्ग को लागू करता है Serializable में।

यह वह इंटरफ़ेस है जो कक्षा को क्रमबद्ध करने में सक्षम बनाता है।

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

प्रत्येक serializable वर्ग के साथ

क्रमबद्धता क्रम सहयोगियों एक संस्करण संख्या, सत्यापित करने के लिए एक serialVersionUID, जो अक्रमांकन दौरान प्रयोग किया जाता है कहा जाता है कि:

ऐसी स्थिति में हमने आधिकारिक ओरेकल प्रलेखन पर एक नज़र हो सकता है एक धारावाहिक ऑब्जेक्ट के प्रेषक और रिसीवर ने उस ऑब्जेक्ट के लिए कक्षाएं लोड की हैं जो क्रमशः के साथ संगत हैं। यदि रिसीवर ने ऑब्जेक्ट के लिए एक वर्ग लोड किया है जिसमें संबंधित प्रेषक की कक्षा की तुलना में एक अलग धारावाहिक VERSIONUID है, तो deserialization के परिणामस्वरूप अमान्य क्लास अपवाद होगा। एक serializable वर्ग अपने serialVersionUID को "serialVersionUID" नामक फ़ील्ड घोषित करके स्पष्ट रूप से घोषित कर सकता है जो स्थैतिक, अंतिम और प्रकार का लंबा होना चाहिए: कोई भी एक्सेस-मॉडिफायर स्थिर अंतिम लंबा धारावाहिक VersionUID = 42L; एक serializable वर्ग स्पष्ट रूप से एक serialVersionUID घोषणा नहीं करता है, तो तो क्रमबद्धता क्रम एक डिफ़ॉल्ट serialVersionUID मूल्य उस वर्ग वर्ग के विभिन्न पहलुओं के आधार पर के लिए, जावा (टीएम) वस्तु क्रमबद्धता विशिष्टता में वर्णित के रूप की गणना करेगा। हालांकि, यह सलाह दी जाती है कि सभी serializable वर्गों स्पष्ट serialVersionUID मूल्यों की घोषणा के बाद से डिफ़ॉल्ट serialVersionUID गणना अत्यधिक करने के लिए वर्ग विवरण संकलक कार्यान्वयन के आधार पर भिन्न हो सकता है कि संवेदनशील है, और इस प्रकार अक्रमांकन दौरान अप्रत्याशित InvalidClassExceptions हो सकती है। इसलिए, एक अलग serialVersionUID विभिन्न जावा कंपाइलर कार्यान्वयन में मूल्य की गारंटी के लिए, एक serializable कक्षा को एक स्पष्ट serialVersionUID मान घोषित करना होगा। यह भी दृढ़ता से सलाह देता है कि स्पष्ट serialVersionUID घोषणाएं निजी संशोधक का उपयोग करें जहां संभव हो, क्योंकि ऐसी घोषणाएं केवल पर लागू होती हैं, तुरंत घोषित कक्षा - सीरियल VersionUID फ़ील्ड विरासत वाले सदस्यों के रूप में उपयोगी नहीं हैं।

आपने गौर किया तो किसी दूसरे कीवर्ड हम इस्तेमाल किया है जो क्षणिक होती है।

यदि कोई क्षेत्र धारावाहिक नहीं है, तो इसे क्षणिक चिह्नित किया जाना चाहिए।यहाँ हम itemCostPrice क्षणिक के रूप में चिह्नित है और यह एक फ़ाइल

अब कैसे फ़ाइल में एक वस्तु का राज्य लिखना और फिर वहाँ से इसे पढ़ने के लिए पर एक नजर डालते हैं में लिखा जा नहीं करना चाहती।

public class SerializationExample { 

    public static void main(String[] args){ 
     serialize(); 
     deserialize(); 
    } 

    public static void serialize(){ 

     Item item = new Item(1L,"Pen", 12.55); 
     System.out.println("Before Serialization" + item); 

     FileOutputStream fileOut; 
     try { 
      fileOut = new FileOutputStream("/tmp/item.ser"); 
      ObjectOutputStream out = new ObjectOutputStream(fileOut); 
      out.writeObject(item); 
      out.close(); 
      fileOut.close(); 
      System.out.println("Serialized data is saved in /tmp/item.ser"); 
      } catch (FileNotFoundException e) { 

        e.printStackTrace(); 
      } catch (IOException e) { 

        e.printStackTrace(); 
      } 
     } 

    public static void deserialize(){ 
     Item item; 

     try { 
       FileInputStream fileIn = new FileInputStream("/tmp/item.ser"); 
       ObjectInputStream in = new ObjectInputStream(fileIn); 
       item = (Item) in.readObject(); 
       System.out.println("Serialized data is read from /tmp/item.ser"); 
       System.out.println("After Deserialization" + item); 
     } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
     } catch (IOException e) { 
       e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
       e.printStackTrace(); 
     } 
    } 
} 

उपर्युक्त में हम किसी ऑब्जेक्ट के क्रमबद्धरण और deserialization का एक उदाहरण देख सकते हैं।

इसके लिए हमने दो वर्गों का उपयोग किया। ऑब्जेक्ट को क्रमबद्ध करने के लिए हमने ऑब्जेक्टऑटपुटस्ट्रीम का उपयोग किया है। हमने फ़ाइल में ऑब्जेक्ट लिखने के लिए विधि writeObject विधि का उपयोग किया है।

Deserializing के लिए हमने ऑब्जेक्ट इनपुटपुट का उपयोग किया है जो फ़ाइल से ऑब्जेक्ट से पढ़ता है। यह फ़ाइल से ऑब्जेक्ट डेटा पढ़ने के लिए readObject का उपयोग करता है।

ऊपर कोड के उत्पादन में किया जाएगा की तरह:

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55] 
Serialized data is saved in /tmp/item.ser 
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null] 

सूचना है कि itemCostPrice deserialized वस्तु सेअशक्त है के रूप में यह नहीं लिखा गया था।

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