2010-01-22 8 views
11

किसी तृतीय पक्ष लाइब्रेरी में एक विशिष्ट श्रेणी है जिसे मैं क्रमबद्ध करना चाहता हूं। मैं ऐसा कैसे कर पाऊंगा?जावा में मैं एक वर्ग को क्रमबद्ध कैसे करूं जो सीरियलज़ेबल चिह्नित नहीं है?

मुझे लगता है कि मुझे कक्षा के किसी ऑब्जेक्ट में एक विधि लिखनी होगी और निजी सदस्य मूल्य प्राप्त करने के लिए प्रतिबिंब का उपयोग करना होगा। फिर deserialization के लिए मैं मूल्यों को वापस रखने के लिए प्रतिबिंब का उपयोग करेंगे।

क्या यह काम करेगा? क्या कोई आसान तरीका है?

+0

क्या आपको इसे संगत w/भविष्य के संस्करणों की आवश्यकता होगी? –

+0

नहीं, इसे भविष्य के संस्करणों के साथ संगत होने की आवश्यकता नहीं है। – Kyle

+0

क्या आप सिर्फ डेटा को जारी रखना चाहते हैं? यदि हां, तो JAXB का उपयोग क्यों न करें? – Boltimuss

उत्तर

12

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

स्यूडोकोड:

class Thirdparty{ 

    int field1; 
    int field; 
} 

class Transfer implements Serializable{ 

    int field1; 
    int field2; 

    /* Constructor takes the third party object as 
     an argument for copying the field values. 
     For private fields without getters 
     use reflection to get the values */ 
    Transfer (Thirdparty orig){ 
     this.field1=orig.field1; 
     this.field2=orig.field2; 
    } 

    ThirdParty getAsThirdParty(){ 
     Thirdparty copy=new ThirdParty(); 
     copy.field1=this.field1; 
     copy.field2=this.field2; 
     return copy; 
    } 

    /* override these methods for custom serialization */ 
    void writeObject(OutputStream sink); 
    void readObject(InputStream src); 
} 

तुम बस कि सदस्यों को सही ढंग से अगर आप क्रमानुसार लगे हुए हैं सुनिश्चित करने के लिए है कोई विशेष सदस्य वस्तुएं मिलीं।

वैकल्पिक रूप से यदि तृतीय पक्ष वर्ग अंतिम नहीं है तो आप इसे विस्तारित कर सकते हैं, क्या इसे सीरियलज़ेबल लागू करना है और अपना खुद का लेखन ऑब्जेक्ट और पढ़ना ऑब्जेक्ट विधियां लिखना है।

कुछ क्रमबद्धता infos के लिए यहाँ देखें:

Serialization Secrets

+0

धन्यवाद, यह अच्छा लगता है, मैं निजी सदस्य चर के बारे में क्या करूँ? क्या इसके लिए कोई आसान तरीका है या मुझे प्रतिबिंब की आवश्यकता है? – Kyle

+0

हाँ प्रतिबिंब एकमात्र तरीका है जिसे मैं गैर दृश्य क्षेत्रों तक पहुंचने के बारे में जानता हूं। : / – fasseg

2

आप कुछ है कि क्रमबद्धता करता है में लपेट की जरूरत है।

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

किसी भी मामले में, रैपर ऑब्जेक्ट को बाइट [] या स्ट्रिंग या कुछ और में परिवर्तित कर देगा और इसे क्रमबद्ध आउटपुट में लिख देगा। Deserialization पर यह उस डेटा से वस्तु का पुनर्निर्माण करता है।

दो तरीकों अपने आवरण को लागू करने की है

private void writeObject(java.io.ObjectOutputStream out) 
throws IOException 
private void readObject(java.io.ObjectInputStream in) 
throws IOException, ClassNotFoundException; 
1

एक बहुत तृतीय पक्ष वर्ग की प्रकृति पर निर्भर कर रहे हैं। क्या यह अंतिम है, क्या इसमें कोई तर्क कन्स्ट्रक्टर नहीं है, क्या आप इसे ज्ञात मानों का निर्माण कर सकते हैं या इसे किसी अन्य वर्ग द्वारा बनाया गया है, क्या इसमें स्वयं गैर-सीरियलज़ेबल सदस्य हैं?

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

0

एक और संभावित समाधान आपके सीरियलज़ेबल क्लास के अंदर निजी विधियों के एक सेट को परिभाषित करने के लिए हो सकता है जो तीसरे पक्ष के वर्ग के उदाहरणों का उपयोग करता है। ये विशेष विधियां धारावाहिक प्रणाली प्रदान करने वाले विशेष कॉलबैक अनुबंध का हिस्सा हैं। इन विधियों को बुलाया जाएगा serialization/deserialization प्रक्रिया के दौरान। उनके हस्ताक्षर होना चाहिए की तरह:

public class MyClass implements Serializable 
{ 
    transient private ThirdParty thirdPartyInstance ; 
    private int myClassVariable ; 
    private void writeObject(ObjectOutputStream oos) 
    { 
     try 
     { 

      oos.defaultWriteObject(); 
      oos.writeInt(thirdPartyInstance.getThirdPartyVariable()); 
      oos.writeInt(thirdPartyInstance.getFourthPartyInstance().getFourthPartyVariable()); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    private void readObject(ObjectInputStream ois) 
    { 
     try 
     { 
      ois.defaultReadObject(); //the call to defaultReadObject method must always be before any other code in the try block 

      //Reconstructing thirdPartyInstance 
thirdPartyInstance =new ThirdParty(ois.readInt(),new FourthParty(ois.readInt())); 

     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    MyClass(int myClassVariable, ThirdParty thirdPartyInstance) 
    { 
     this.myClassVariable=myClassVariable; 
     this.thirdPartyInstance=thirdPartyInstance; 
    } 
    ThirdParty getThirdPartyInstance() 
    { 
     return thirdPartyInstance; 
    } 

    int getMyClassVariable() 
    { 
     return myClassVariable; 
    } 

    public static void main(String args[]) 
    { 
     FourthParty fourthPartyInstance=new FourthParty(45); 
     ThirdParty thirdPartyInstance=new ThirdParty(13,fourthPartyInstance); 
     MyClass myClassInstance=new MyClass(7,thirdPartyInstance); 
     System.out.println("Before: ThirdParty variable value is "+myClassInstance.getThirdPartyInstance().getThirdPartyVariable()); 
     System.out.println("Before: FourthParty variable value is "+myClassInstance.getThirdPartyInstance().getFourthPartyInstance().getFourthPartyVariable()); 
     System.out.println("Before: MyClass variable value is "+myClassInstance.getMyClassVariable()); 
     try 
     {  
      FileOutputStream fios=new FileOutputStream("D://TestFileq.ser"); 
      ObjectOutputStream oos=new ObjectOutputStream(fios); 
      oos.writeObject(myClassInstance); 
      oos.close(); 


      FileInputStream fi = new FileInputStream("D://TestFileq.ser"); 
      ObjectInputStream objectIn = new ObjectInputStream(fi); 
      MyClass myClassInst = (MyClass)objectIn.readObject(); 
      System.out.println("After: ThirdParty variable value is "+myClassInst.getThirdPartyInstance().getThirdPartyVariable()); 
      System.out.println("After: FourthParty variable value is "+myClassInst.getThirdPartyInstance().getFourthPartyInstance().getFourthPartyVariable()); 
      System.out.println("After:MyClass variable value is "+myClassInst.getMyClassVariable()); 

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

    } 

} 
class ThirdParty 
{ 
    private int thirdPartyVariable; 
    private FourthParty fourthPartyInstance; 
    ThirdParty(int thirdPartyVariable,FourthParty fourthPartyInstance) 
    { 
     this.thirdPartyVariable=thirdPartyVariable; 
     this.fourthPartyInstance=fourthPartyInstance; 
    } 
    int getThirdPartyVariable() 
    { 
     return thirdPartyVariable; 
    } 
    FourthParty getFourthPartyInstance() 
    { 
     return fourthPartyInstance; 
    } 


} 
class FourthParty 
{ 
    private int fourthPartyVariable; 
    FourthParty(int fourthPartyVariable) 
    { 
     this.fourthPartyVariable=fourthPartyVariable; 
    } 
    int getFourthPartyVariable() 
    { 
     return fourthPartyVariable; 
    } 


} 

ध्यान दें कि MyClass में thirdPartyInstance क्षणिक अन्यथा प्रकार का एक अपवाद घोषित किया जाना चाहिए 'java.io.NotSerializableException': यह उदाहरण

private void writeObject(ObjectOutputStream os) { 
// your code for saving the third party variables 
} 
private void readObject(ObjectInputStream is) { 
// your code to read the third party state, create a new ThirdParty instance, 
// and assign it to your class. 
} 

आगे इस विचार को स्पष्ट करता है होता है। अधिक स्पष्टीकरण के लिए देखें: 'कैथी सिएरा' द्वारा जावा 6 के लिए एससीजेपी सन प्रमाणित प्रोग्रामर, पृष्ठ संख्या 497

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

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