Serializable का क्या अर्थ है?


136

वास्तव Serializableमें जावा में एक वर्ग होने का क्या मतलब है ? या सामान्य तौर पर, इस मामले के लिए ...


10
@skaffman यहां क्लास के लिए क्या कहते हैं Serializable: Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.
रित्विक बोस

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

जवाबों:


132

उदाहरण के लिए डिस्क पर सहेजने के लिए सीरियल ऑब्जेक्ट को मेमोरी से बिट्स के एक क्रम तक बना रहा है। Deserialization इसके विपरीत है - डिस्क से हाइड्रेट / ऑब्जेक्ट बनाने के लिए डेटा पढ़ना।

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


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

1
इसलिए जब हम "ऑब्जेक्ट्स" के बारे में बात कर रहे हैं, तो क्या हमारा मतलब है कि किसी क्लास, या असेंबली, फाइल आदि जैसे किसी भी "सॉफ्टवेयर ऑब्जेक्ट्स" को इंस्टेंट किया जाए? और अगर इसका उत्तरार्द्ध है, तो क्या यह केवल कार्यक्रमों और वातावरण के बीच डेटा भेजने का एक मानकीकृत तरीका है?
Sunburst275

1
@ Sunburst275 - इस मामले में, यह स्मृति में एक वर्ग के मेमोरी प्रतिनिधित्व में है - अर्थात एक कक्षा का एक उदाहरण (असेंबली के क्रमांकन के बारे में बात करने के लिए कोई वास्तविक बिंदु नहीं है, क्योंकि वे आमतौर पर फ़ाइलों के रूप में डिस्क पर होते हैं जो कर सकते हैं बस के रूप में चारों ओर भेजा जा रहा है)।
ओड

44

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

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

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";

आप उस धारा को कई धाराओं में क्रमबद्ध कर सकते हैं। मैं दो धाराओं के लिए करूंगा:

मानक उत्पादन के लिए सरलीकरण:

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 serializeToFile(Person person) throws IOException {
        OutputStream outStream = new FileOutputStream("person.ser");
        ObjectOutputStream fileObjectOut = new ObjectOutputStream(outStream);
        fileObjectOut.writeObject(person);
        fileObjectOut.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();
    }

धन्यवाद। मुझे लगता है कि मुझे अब मिल गया है।
सनबर्स्ट 275

40

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


15

यहाँ Serialization की एक विस्तृत व्याख्या है : (मेरा अपना ब्लॉग)

क्रमबद्धता:

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

Serialization की क्या आवश्यकता है?

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

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

पहले आइए एक नजर डालते हैं आइटम क्लास पर:

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;
        }
}

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

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

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

उसके लिए हम आधिकारिक Oracle दस्तावेज पर एक नज़र डाल सकते हैं:

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

यदि आपने देखा है कि एक और खोजशब्द है जिसका हमने उपयोग किया है जो क्षणिक है

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

अब आइए नजर डालते हैं कि फाइल में किसी ऑब्जेक्ट की स्थिति कैसे लिखी जाए और फिर उसे वहां से पढ़ें।

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();
        }
     }
}

उपर्युक्त में हम किसी वस्तु के क्रमांकन और विलयन का उदाहरण देख सकते हैं।

उसके लिए हमने दो वर्गों का उपयोग किया। ऑब्जेक्ट को क्रमबद्ध करने के लिए हमने ObjectOutputStream का उपयोग किया है। हमने फाइल में ऑब्जेक्ट लिखने के लिए मेथड राइट ऑबजेक्ट का इस्तेमाल किया है।

Deserializing के लिए हमने ObjectInputStream का उपयोग किया है जो फ़ाइल से ऑब्जेक्ट से पढ़ता है। यह फ़ाइल से ऑब्जेक्ट डेटा को पढ़ने के लिए 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]

ध्यान दें कि deserialized ऑब्जेक्ट से itemCostPrice शून्य है क्योंकि यह नहीं लिखा गया था।


2
इस विस्तृत विवरण के लिए धन्यवाद।
प्रॉमिस

यह एक अच्छा स्पष्टीकरण है! धन्यवाद! लेकिन ईमानदार होने के लिए, यह प्रविष्टि आपके ब्लॉग पर एक से अधिक साफ दिखती है। वैसे भी, इससे बहुत मदद मिली!
सनबर्स्ट 275

11

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


1
यह परिभाषा अधिक सटीक लगती है। धन्यवाद।
प्रॉमिस

6

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

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


5
यह 'संकलक के लिए ध्वज' नहीं है। यह क्रमिक रूप से क्रमांकन उपतंत्र का ध्वज है।
लोर्न

1
@ ईजेपी - धन्यवाद, पता नहीं था कि
ApxxMunky

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

19
अगर मैंने इसे नहीं लिखा होता तो मैं सुधारा नहीं जाता और खराब हो जाता। अन्य सभी उत्तरों ने क्षणिक को भी छोड़ दिया है। आपने एक उत्तर भी नहीं लिखा, आप बस अन्य लोगों को ट्रोल कर रहे हैं।
AphexMunky

4

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

आंकड़ों के साथ स्पष्ट अन्वेषण के लिए। और अधिक जानकारी के लिए यहां देखें


2

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

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


2

सीरियलाइजेशन: फाइल / नेटवर्क या कहीं भी लिखने की वस्तु की स्थिति। (मतलब जावा ऑब्जेक्ट समर्थित फॉर्म फाइल सपोर्टेड फॉर्म या नेटवर्क सपोर्टेड फॉर्म के लिए)

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


1

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

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