Java में Serializable और Externalizable के बीच अंतर क्या है?


जवाबों:


267

लागू करने से, अन्य उत्तरों को जोड़ने के लिए java.io.Serializable , आपको अपनी कक्षा की वस्तुओं के लिए "स्वचालित" क्रमांकन क्षमता मिलती है। किसी अन्य तर्क को लागू करने की आवश्यकता नहीं है, यह सिर्फ काम करेगा। जावा रनटाइम प्रतिबिंब का उपयोग यह पता लगाने के लिए करेगा कि आपकी वस्तुओं को मार्शल और अनमर्श कैसे किया जाए।

जावा के पुराने संस्करण में, प्रतिबिंब बहुत धीमा था, और इसलिए बड़े ऑब्जेक्ट ग्राफ़ (जैसे क्लाइंट-सर्वर आरएमआई अनुप्रयोगों में) को क्रमबद्ध करना एक प्रदर्शन समस्या थी। इस स्थिति को संभालने के लिए, java.io.Externalizableइंटरफ़ेस प्रदान किया गया था, जो कि java.io.Serializableकस्टम-लिखित तंत्र के साथ मार्शलिंग और अनमर्सहेलिंग फ़ंक्शन करने के लिए है (आपको अपनी कक्षा पर लागू करने readExternalऔर writeExternalविधियों की आवश्यकता है )। यह आपको प्रतिबिंब प्रदर्शन की अड़चन के आसपास जाने का साधन देता है।

जावा के हाल के संस्करणों में (1.3 बाद में, निश्चित रूप से) प्रतिबिंब का प्रदर्शन काफी हद तक बेहतर है जितना कि इसका उपयोग किया जाता है, और इसलिए यह एक समस्या से बहुत कम है। मुझे संदेह है कि Externalizableआधुनिक JVM से सार्थक लाभ पाने के लिए आपको कड़ी मेहनत करनी होगी ।

इसके अलावा, अंतर्निहित जावा क्रमांकन तंत्र केवल एक ही नहीं है, आप तीसरे पक्ष के प्रतिस्थापन, जैसे कि जेबीओस सीरियलाइज़ेशन, जो कि काफी तेज है, और डिफ़ॉल्ट के लिए एक ड्रॉप-इन प्रतिस्थापन हो सकता है।

इसका एक बड़ा पहलू यह Externalizableहै कि आपको इस तर्क को स्वयं बनाए रखना होगा - यदि आप अपनी कक्षा में कोई फ़ील्ड जोड़ते हैं, हटाते हैं या बदलते हैं, तो आपको इसके लिए अपने तरीकों writeExternal/ readExternalतरीकों को बदलना होगा।

संक्षेप में, Externalizableजावा 1.1 दिनों का एक अवशेष है। वहाँ वास्तव में इसके लिए कोई ज़रूरत नहीं है।


61
इन बेंचमार्क के अनुसार नहीं: [ code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking] , मैनुअल सीरियलाइज़ेशन (एक्सटर्नेबिल का उपयोग करना), जावा के डिफ़ॉल्ट क्रमांकन का उपयोग करने की तुलना में बहुत तेज़ है। अगर आपके काम के लिए गति मायने रखती है, तो निश्चित रूप से अपने खुद के सीरियल-निर्माता को लिखें।
15

6
नए लिंक पर अपडेट करना github.com/eishay/jvm-serializers/wiki @Jack द्वारा सुझाया गया
noquery

3
"जावा-पुस्तिका" में github.com/eishay/jvm-serializers/wiki करता नहीं Externalizable का उपयोग करें, जो ObjectOutputStream का उपयोग कर अर्थ होगा। कोड के लिंक के लिए github.com/eishay/jvm-serializers/wiki/ToolBehavior देखें । इसके बजाय, यह हाथ से लिखा कोड है जो DataOutputStream का उपयोग करता है, इसलिए यह उन चीज़ों से ग्रस्त नहीं है जो ObjectOutputStream को धीमा करते हैं (जैसे कि ऑब्जेक्ट इंस्टेंस का ट्रैक रखना और ऑब्जेक्ट साइकिल का समर्थन करना)।
एस्को लुओंटोला

7
अपने आप को तर्क बनाए रखने के लिए केवल एक नकारात्मक पक्ष है यदि वर्ग कभी नहीं बदलता है और आपको पुराने डेटा के लगातार संस्करणों में पढ़ना नहीं पड़ता है। यदि आप चाहते हैं कि इसके पुराने संस्करणों को डिस्क्राइब करने के लिए नारकीय कोड लिखे बिना अपनी कक्षा को बदलने की स्वतंत्रता बहुतExternalizable मदद करती है
टिम बौडर्यू

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

37

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

  ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream("/Users/Desktop/files/temp.txt"));
        oos.writeObject(linkedListHead); //writing head of linked list
        oos.close();

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

public class MyExternalizable implements Externalizable
{

private String userName;
private String passWord;
private Integer roll;

public MyExternalizable()
{

}

public MyExternalizable(String userName, String passWord, Integer roll)
{
    this.userName = userName;
    this.passWord = passWord;
    this.roll = roll;
}

@Override
public void writeExternal(ObjectOutput oo) throws IOException 
{
    oo.writeObject(userName);
    oo.writeObject(roll);
}

@Override
public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException 
{
    userName = (String)oi.readObject();
    roll = (Integer)oi.readObject();
}

public String toString()
{
    StringBuilder b = new StringBuilder();
    b.append("userName: ");
    b.append(userName);
    b.append("  passWord: ");
    b.append(passWord);
    b.append("  roll: ");
    b.append(roll);

    return b.toString();
}
public static void main(String[] args)
{
    try
    {
        MyExternalizable m  = new MyExternalizable("nikki", "student001", 20);
        System.out.println(m.toString());
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/Desktop/files/temp1.txt"));
        oos.writeObject(m);
        oos.close();

        System.out.println("***********************************************************************");
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/Desktop/files/temp1.txt"));
        MyExternalizable mm = (MyExternalizable)ois.readObject();
        mm.toString();
        System.out.println(mm.toString());
    } 
    catch (ClassNotFoundException ex) 
    {
        Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch(IOException ex)
    {
        Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
    }
}
}

यहां यदि आप डिफॉल्ट कंस्ट्रक्टर पर टिप्पणी करते हैं तो कोड अपवाद से नीचे फेंक देगा:

 java.io.InvalidClassException: javaserialization.MyExternalizable;     
 javaserialization.MyExternalizable; no valid constructor.

हम यह देख सकते हैं कि पासवर्ड संवेदनशील जानकारी है, इसलिए मैं इसे writeExternal (ObjectOutput oo) विधि में क्रमबद्ध नहीं कर रहा हूं और readExternal (ObjectInput oi) में इसका मान सेट नहीं कर रहा हूं। यही लचीलापन है जो एक्सट्रैक्टेबल द्वारा प्रदान किया गया है।

उपरोक्त कोड का आउटपुट निम्नानुसार है:

userName: nikki  passWord: student001  roll: 20
***********************************************************************
userName: nikki  passWord: null  roll: 20

हम निरीक्षण कर सकते हैं क्योंकि हम पासवर्ड के मूल्य को निर्धारित नहीं कर रहे हैं इसलिए यह अशक्त है।

पासवर्ड फ़ील्ड को क्षणिक घोषित करके भी इसे प्राप्त किया जा सकता है।

private transient String passWord;

आशा करता हूँ की ये काम करेगा। अगर मैंने कोई गलती की तो मैं माफी मांगता हूं। धन्यवाद।


22

Serializableऔर के बीच महत्वपूर्ण अंतरExternalizable

  1. मार्कर इंटरफ़ेस : Serializableकिसी भी तरीके के बिना मार्कर इंटरफ़ेस है। Externalizableइंटरफ़ेस में दो विधियाँ शामिल हैं: writeExternal()और readExternal()
  2. सीरियलाइज़ेशन प्रक्रिया : Serializableइंटरफ़ेस को लागू करने वाली कक्षाओं के लिए डिफ़ॉल्ट सीरियलाइज़ेशन प्रक्रिया को किक-इन किया जाएगा । प्रोग्रामर परिभाषित सीरियलाइज़ेशन प्रक्रिया Externalizableइंटरफ़ेस को लागू करने वाली कक्षाओं के लिए किक-इन होगी ।
  3. रखरखाव : असंगत परिवर्तन क्रमांकन को तोड़ सकते हैं।
  4. बैकवर्ड संगतता और नियंत्रण : यदि आपको कई संस्करणों का समर्थन करना है, तो आप Externalizableइंटरफ़ेस के साथ पूर्ण नियंत्रण रख सकते हैं । आप अपनी वस्तु के विभिन्न संस्करणों का समर्थन कर सकते हैं। यदि आप कार्यान्वित करते हैं Externalizable, तो superकक्षा को क्रमबद्ध करना आपकी ज़िम्मेदारी है
  5. सार्वजनिक नो-आर्ग कंस्ट्रक्टर : Serializableऑब्जेक्ट का निर्माण करने के लिए प्रतिबिंब का उपयोग करता है और किसी आर्ग कंस्ट्रक्टर की आवश्यकता नहीं होती है। लेकिन Externalizableसार्वजनिक नहीं- arg निर्माता की मांग करता है।

का संदर्भ लें ब्लॉग से Hitesh Gargअधिक जानकारी के लिए।


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

1
फिर से वाक्य वाक्य।
रवींद्र बाबू

सीरियलाइजेशन युक्ति के लिंक को साझा करने के लिए धन्यवाद।
JL_SO

21

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

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


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

9

ऑब्जेक्ट सीरियलाइज़ेशन सीरीज़ेबल और एक्सटर्नेबल इंटरफेस का उपयोग करता है। एक जावा ऑब्जेक्ट केवल सीरियल करने योग्य है। यदि कोई वर्ग या उसका कोई भी सुपरक्लास java.io.Serializable इंटरफ़ेस या उसके सबडाइरेक्ट, java.io.Externalizable को लागू करता है। अधिकांश जावा वर्ग क्रमबद्ध हैं

  • NotSerializableException: packageName.ClassName«क्रमबद्धता प्रक्रिया में एक क्लास ऑब्जेक्ट में भाग लेने के लिए, क्लास को सीरियल या एक्सटर्नेबल इंटरफ़ेस लागू करना चाहिए।

यहां छवि विवरण दर्ज करें


सीरियल इंटरफ़ेस

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

package java.io;

public interface Serializable {};
  • क्रमांकन इंटरफ़ेस की कोई विधियाँ या क्षेत्र नहीं हैं और केवल क्रमिक होने के शब्दार्थों की पहचान करने के लिए कार्य करता है। किसी वर्ग को क्रमबद्ध / निरूपित करने के लिए, या तो हम डिफ़ॉल्ट राइटऑबजेक्ट और रीडऑब्जेक्ट विधियों का उपयोग कर सकते हैं (या) हम एक वर्ग से राइटऑबजेक्ट और रीडऑब्जेक्ट विधियों को ओवरराइड कर सकते हैं।
  • वस्तु को क्रमबद्ध करने में JVM का पूर्ण नियंत्रण होगा। क्षणिक कीवर्ड का उपयोग करेंडेटा सदस्य को क्रमबद्ध होने से रोकने के लिए का ।
  • यहां धारावाहिक योग्य वस्तुओं को बिना निष्पादित किए सीधे स्ट्रीम से पुनर्निर्मित किया जाता है
  • InvalidClassException« Deserialization प्रक्रिया में, अगर स्थानीय वर्ग serialVersionUID मान संबंधित प्रेषक वर्ग से अलग है। फिर परिणाम संघर्ष के रूप में java.io.InvalidClassException: com.github.objects.User; local class incompatible: stream classdesc serialVersionUID = 5081877, local class serialVersionUID = 50818771
  • वर्ग के गैर-क्षणिक और गैर-स्थिर क्षेत्रों के मूल्य क्रमबद्ध हो जाते हैं।

बाहरी इंटरफ़ेस

बाहरी वस्तुओं के लिए, केवल वस्तु के वर्ग की पहचान कंटेनर द्वारा बचाई जाती है; वर्ग को सामग्री को सहेजना और पुनर्स्थापित करना होगा। बाहरी इंटरफ़ेस निम्नानुसार परिभाषित किया गया है:

package java.io;

public interface Externalizable extends Serializable
{
    public void writeExternal(ObjectOutput out)
        throws IOException;

    public void readExternal(ObjectInput in)
        throws IOException, java.lang.ClassNotFoundException;
}
  • बाहरी इंटरफ़ेस में दो विधियाँ होती हैं, एक बाहरी वस्तु को किसी वस्तु की स्थिति को बचाने / पुनर्स्थापित करने के लिए writeExternal और readExternal विधियों को लागू करना चाहिए।
  • प्रोग्रामर को इस बात का ध्यान रखना होता है कि किन वस्तुओं को क्रमबद्ध किया जाए। एक प्रोग्रामर Serialization So का ध्यान रखता है, इसलिए यहां क्षणिक कीवर्ड Serialization प्रक्रिया में किसी भी ऑब्जेक्ट को प्रतिबंधित नहीं करेगा।
  • जब एक बाहरी वस्तु को फिर से संगठित किया जाता है, तो एक उदाहरण सार्वजनिक नो-आर्ग कंस्ट्रक्टर का उपयोग करके बनाया जाता है, फिर रीडऑर्नेटिक विधि कहा जाता है। किसी ऑब्जेक्टइन्स्ट्रीमस्ट्रीम से पढ़कर सीरियल की जाने योग्य वस्तुओं को पुनर्स्थापित किया जाता है।
  • OptionalDataException« जैसा कि हमने उन्हें लिखा था, वैसे ही खेतों को उसी क्रम और प्रकार में होना चाहिए। यदि स्ट्रीम से कोई भी बेमेल प्रकार है, तो यह OptionalDataException फेंकता है।

    @Override public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt( id );
        out.writeUTF( role );
        out.writeObject(address);
    }
    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this.id = in.readInt();
        this.address = (Address) in.readObject();
        this.role = in.readUTF();
    }
  • वर्ग के उदाहरण क्षेत्र जो क्रमबद्ध होने के लिए (उजागर) लिखे गए ObjectOutputहैं।


उदाहरण « लागू करता है सीरियल

class Role {
    String role;
}
class User extends Role implements Serializable {

    private static final long serialVersionUID = 5081877L;
    Integer id;
    Address address;

    public User() {
        System.out.println("Default Constructor get executed.");
    }
    public User( String role ) {
        this.role = role;
        System.out.println("Parametarised Constructor.");
    }
}

class Address implements Serializable {

    private static final long serialVersionUID = 5081877L;
    String country;
}

उदाहरण « लागू करने योग्य

class User extends Role implements Externalizable {

    Integer id;
    Address address;
    // mandatory public no-arg constructor
    public User() {
        System.out.println("Default Constructor get executed.");
    }
    public User( String role ) {
        this.role = role;
        System.out.println("Parametarised Constructor.");
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt( id );
        out.writeUTF( role );
        out.writeObject(address);
    }
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this.id = in.readInt();
        this.address = (Address) in.readObject();
        this.role = in.readUTF();
    }
}

उदाहरण

public class CustomClass_Serialization {
    static String serFilename = "D:/serializable_CustomClass.ser";

    public static void main(String[] args) throws IOException {
        Address add = new Address();
        add.country = "IND";

        User obj = new User("SE");
        obj.id = 7;
        obj.address = add;

        // Serialization
        objects_serialize(obj, serFilename);
        objects_deserialize(obj, serFilename);

        // Externalization
        objects_WriteRead_External(obj, serFilename);
    }

    public static void objects_serialize( User obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        // java.io.NotSerializableException: com.github.objects.Address
        objectOut.writeObject( obj );
        objectOut.flush();
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");
    }
    public static void objects_deserialize( User obj, String serFilename ) throws IOException{
        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            User user = (User) readObject;
            System.out.format("Obj[Id:%d, Role:%s] \n", user.id, user.role);

            Address add = (Address) user.address;
            System.out.println("Inner Obj : "+ add.country );
            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void objects_WriteRead_External( User obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            User user = new User();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            user.readExternal(ois);

            System.out.format("Obj[Id:%d, Role:%s] \n", user.id, user.role);

            Address add = (Address) user.address;
            System.out.println("Inner Obj : "+ add.country );
            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

@देख


7

वर्णनात्मक इंटरफ़ेस वास्तव में क्रमांकन प्रक्रिया के प्रदर्शन का अनुकूलन करने के लिए प्रदान नहीं किया गया था! लेकिन अपने स्वयं के कस्टम प्रसंस्करण को लागू करने के साधन प्रदान करने और एक वस्तु और उसके सुपर प्रकारों के लिए स्ट्रीम के प्रारूप और सामग्री पर पूर्ण नियंत्रण प्रदान करने के लिए!

इसके उदाहरण एएमएफ (एक्शनस्क्रिप्ट संदेश प्रारूप) का कार्यान्वयन है जो नेटवर्क पर मूल क्रिया स्क्रिप्ट ऑब्जेक्ट को स्थानांतरित करने के लिए रीमोटिंग है।


7

https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html

डिफ़ॉल्ट क्रमांकन कुछ क्रिया है, और क्रमबद्ध वस्तु के व्यापक संभव उपयोग परिदृश्य को मानता है, और तदनुसार डिफ़ॉल्ट प्रारूप (सीरियल) क्रमिक ऑब्जेक्ट के वर्ग के बारे में जानकारी के साथ परिणामी धारा को एनोटेट करता है।

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

अतिरिक्त रूप से (उरी बिंदु के रूप में) बाह्यकरण जावा प्रकार के अनुरूप स्ट्रीम में डेटा के एन्कोडिंग पर पूर्ण नियंत्रण प्रदान करता है। (एक आकस्मिक) उदाहरण के लिए, आप बूलियन को 'वाई' के रूप में और 'एन' के रूप में गलत रिकॉर्ड करना चाह सकते हैं। बाहरीकरण आपको ऐसा करने की अनुमति देता है।


2

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


2

Serializable और Externalizable के बीच बहुत सारे अंतर मौजूद हैं, लेकिन जब हम कस्टम Serializable (overrided writeObject () और readObject ()) और Externalable के बीच अंतर की तुलना करते हैं, तो हम पाते हैं कि कस्टम कार्यान्वयन ObjectOutputStream वर्ग के लिए कसकर बाइंड होता है जहां बाहरी मामले में, हम अपने आप को ObjectOutput का एक कार्यान्वयन प्रदान करें जो ObjectOutputStream क्लास हो सकता है या यह कुछ अन्य हो सकता है जैसे org.apache.mina.filter.codec.serialization.ObjectSerializationOutputStream

बाहरी इंटरफ़ेस के मामले में

@Override
public void writeExternal(ObjectOutput out) throws IOException {
    out.writeUTF(key);
    out.writeUTF(value);
    out.writeObject(emp);
}

@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    this.key = in.readUTF();
    this.value = in.readUTF();
    this.emp = (Employee) in.readObject();
}





**In case of Serializable interface**


        /* 
             We can comment below two method and use default serialization process as well
             Sequence of class attributes in read and write methods MUST BE same.
        // below will not work it will not work . 
        // Exception = java.io.StreamCorruptedException: invalid type code: 00\
              private void writeObject(java.io.ObjectOutput stream) 
              */
            private void writeObject(java.io.ObjectOutputStream Outstream)
                    throws IOException {

                System.out.println("from writeObject()");
                /*     We can define custom validation or business rules inside read/write methods.
 This way our validation methods will be automatically 
    called by JVM, immediately after default serialization 
    and deserialization process 
    happens.
                 checkTestInfo();
                */

                stream.writeUTF(name);
                stream.writeInt(age);
                stream.writeObject(salary);
                stream.writeObject(address);
            }

            private void readObject(java.io.ObjectInputStream Instream)
                    throws IOException, ClassNotFoundException {
                System.out.println("from readObject()");
                name = (String) stream.readUTF();
                age = stream.readInt();
                salary = (BigDecimal) stream.readObject();
                address = (Address) stream.readObject();
                // validateTestInfo();
            }

मैंने बेहतर समझाने के लिए नमूना कोड जोड़ा है। कृपया देखें / बाहर वस्तु के मामले में बाहर की जाँच करें। ये सीधे किसी भी कार्यान्वयन के लिए बाध्य नहीं हैं।
जहाँ आउटस्ट्रीम / इन्स्ट्रीम को कसकर कक्षाओं में बाँधा जाता है। हम ObjectOutputStream / ObjectInputStream का विस्तार कर सकते हैं लेकिन इसका उपयोग करना थोड़ा मुश्किल होगा।


1
क्या आप इसे अधिक विस्तृत कर सकते हैं? जैसा कि मैंने इसे पढ़ा, मुझे समझ नहीं आया कि आप क्या कहना चाह रहे हैं। इसके अलावा, यदि आप कुछ पैराग्राफ और उदाहरणों के साथ पाठ को प्रारूपित कर सकते हैं, तो यह एक शानदार उत्तर हो सकता है।
शिरकाम

0

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


0

कुछ अंतर:

  1. सीरियलाइजेशन के लिए उस वर्ग के डिफॉल्ट कंस्ट्रक्टर की कोई आवश्यकता नहीं है क्योंकि ऑब्जेक्ट क्योंकि जेवीएम रिफ्लेक्शन एपीआई की मदद से निर्माण करता है। बाहरी संदूषण के मामले में बिना arg के साथ की आवश्यकता होती है, क्योंकि नियंत्रण प्रोग्रामर के हाथ में है और बाद में बसने वालों के माध्यम से ऑब्जेक्ट के लिए deserialized डेटा असाइन करें।

  2. क्रमांकन में यदि उपयोगकर्ता क्रमबद्ध होने के लिए कुछ गुणों को छोड़ना चाहता है, तो उस गुण को चिह्नित करना होगा, जैसे कि इसके विपरीत, बाहरीकरण के लिए आवश्यक नहीं है।

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

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