2012-05-04 16 views
16

ऐसा कहा जाता है कि जावा का डिफ़ॉल्ट क्रमिकरण तंत्र बहुत प्रभावी नहीं है क्योंकि ए) यह पता लगाता है कि कौन से फ़ील्ड प्रतिबिंब के माध्यम से लिखने/पढ़ने के लिए आमतौर पर धीमे होते हैं बी) यह स्ट्रीम करने के लिए अतिरिक्त डेटा लिखता है।जावा: लिखने की दक्षता ऑब्जेक्ट बनाम लिखना बाहरी

इसे और अधिक कुशल बनाने का एक तरीका बाहरी और लागू करने के लिए बाहरी/पढ़ने के बाहरी तरीकों को लागू करना है।

यहां प्रश्न है: यदि मैं इसके बजाय 'writeObject/readObject' विधियों को प्रदान करता हूं और उनमें deafiltWriteObject/defaultReadObject को कॉल नहीं करता हूं, तो यह तंत्र प्रतिबिंब का उपयोग नहीं करेगा यह जानने के लिए कि कौन से फ़ील्ड लिखना/पढ़ना है, साथ ही यह जीता स्ट्रीम करने के लिए अतिरिक्त डेटा नहीं लिखेंगे (या यह सुनिश्चित होगा?)। तो एक दक्षता परिप्रेक्ष्य से, बाह्यकरण लागू करने के समान ऊपर लिखने के लिए लिखने के लिए ऑब्जेक्ट/readObject लागू कर रहा है? या क्या बाद का विकल्प कुछ और व्यावहारिक लाभ देता है जो पूर्व नहीं करता है?

संपादित करें: एक अंतर है, बेशक, जब एक Serializable वर्ग readObject/writeObject को लागू करने subclassed है है, और अगर उपवर्ग का अपना readObject/writeObject है, वे सुपर के readObject/writeObject कॉल करने के लिए की जरूरत नहीं है। ऐसा नहीं है अगर सुपर/सबक्लास इसके बजाय बाहरीकरण लागू करता है। इस मामले में, सुपर का लेखन बाहरी/पढ़ा जाने वाला बाहरी रूप स्पष्ट रूप से बुलाया जाना चाहिए। हालांकि, यह अंतर एक दक्षता बिंदु से अप्रासंगिक है।

उत्तर

7

अभी भी कॉल करने के लिए कौन सा वर्ग/लिखना ऑब्जेक्ट/readObject चुनने में कुछ शीर्ष है। लेकिन यह काफी कम हो गया है।

यह आपके द्वारा किए जा रहे अतिरिक्त विकल्पों का उपयोग करने के आधार पर बाहरी के समान ही कर सकता है और क्या आप इसे अतिरिक्त विकल्प का उपयोग करते हैं। जैसे readObject आपको हर बार एक नई वस्तु बनाने के लिए मानता है, बाहरी पढ़ने योग्य पढ़ा जाता है जिसका अर्थ है कि आप वस्तुओं का पुन: उपयोग कर सकते हैं।

http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/input.html

कई मामलों में, रीसाइक्लिंग वस्तुओं अक्रमांकन को तेज करने में "अगला" कदम है।

http://vanillajava.blogspot.co.uk/2011/10/recycling-objects-to-improve.html

+0

क्या आप pl। इसे थोड़ा और समझाएं: "अभी भी कॉल करने के लिए कौन सा वर्ग/लिखना ऑब्जेक्ट/पढ़ना ऑब्जेक्ट चुनने में कुछ सिर है।" इसके अलावा, 'readResolve' 'बाहरी' अनुबंध का हिस्सा नहीं है, है ना?तो मैं थोड़ा उलझन में हूँ। – shrini1000

+0

यह निर्धारित करना है कि कौन सी कक्षा को पढ़ने के लिए ऑब्जेक्ट या पढ़ा जाता है जब तक कि आप इसे स्वयं भी नहीं करते। readResolve एक वैकल्पिक विधि है जिसे आप Serailizable के साथ भी उपयोग कर सकते हैं। अधिक जानकारी के लिए पहला लिंक देखें। –

+1

Thx। मैंने readResolve का उपयोग किया है, लेकिन उलझन में आया क्योंकि आपने बाहरीकरण के संबंध में इसका उल्लेख किया है। बीटीडब्ल्यू, मैंने आपका लेख पढ़ा। अच्छा था। मैंने वहां एक सवाल पूछा है। यदि आप pl कर सकते हैं तो यह बहुत अच्छा होगा। जवाब दे दो। – shrini1000

1

मिले चीजों के एक जोड़े हैं, जबकि प्रयोग और क्रमबद्धता तंत्र के कोड के माध्यम से जा (यह मानते हुए कि आप के लिए एक विकल्प है):

1) यदि वस्तु Externalizable हो पाया है, यह Externalizable लिए डाली है , और इसी विधि को बुलाया जाता है; जबकि Serializable ऑब्जेक्ट के लिए, यह प्रतिबिंबित रूप से चेक किया गया है अगर यह पढ़ा है ऑब्जेक्ट/writeObject। तो हो सकता है कि यह थोड़ा धीमा हो,

2) बाहरी के लिए लिखे गए डेटा की मात्रा readObject/writeObject के साथ Serializable से थोड़ा कम है (जब मैंने बी के ऑब्जेक्ट को लिखा था तो मुझे निम्नलिखित कोड के लिए 1 बाइट का अंतर मिला) ।

Externalizable के लिए:

static class A implements Externalizable 
{ 
    @Override 
    public void writeExternal(ObjectOutput out) throws IOException 
    { 
     System.out.println("A write called"); 
    } 

    @Override 
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 
    { 
     System.out.println("A read called"); 
    }  
} 

static class B extends A implements Externalizable 
{  
    @Override 
    public void writeExternal(ObjectOutput out) throws IOException 
    { 
     super.writeExternal(out); 
     System.out.println("B write called"); 
    } 

    @Override 
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 
    { 
     super.readExternal(in); 
     System.out.println("B read called"); 
    }  
} 

Serializable के लिए:

static class A implements Serializable 
{ 
    private void writeObject(ObjectOutputStream out) throws IOException 
    { 
     System.out.println("A write called"); 
    } 

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException 
    { 
     System.out.println("A read called"); 
    }  
} 

static class B extends A implements Serializable 
{  
    private void writeObject(ObjectOutputStream out) throws IOException 
    {   
     System.out.println("B write called"); 
    } 

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException 
    {   
     System.out.println("B read called"); 
    }  
} 
2

प्रमुख अंतर यह है, वर्ग डिजाइन के मामले में, यह है कि Serializable, किसी भी वर्ग पर काम करेंगे जबकि Externalizable केवल अस्थायी वर्गों पर काम करता है सार्वजनिक डिफ़ॉल्ट (नो-Arg) रचनाकारों के साथ।

+0

क्या उन्हें वास्तव में उत्परिवर्तनीय होने की आवश्यकता है? मेरा मतलब है, क्या मैं ऐसा कुछ नहीं कर सकता? http://www.byteslounge.com/tutorials/java-externalizable-example – shrini1000

+0

@ shrini1000, आप ऐसा कर सकते हैं, लेकिन 'उपयोगकर्ता' वर्ग थ्रेड-सुरक्षित नहीं है। हालांकि सभी क्षेत्रों को 'अस्थिर' बनाना इसे ठीक करना चाहिए, इसलिए अंत में, आप सही हैं, कक्षा सख्ती से बोलती नहीं है, उत्परिवर्तनीय होना चाहिए। – nilskp

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