2011-10-05 15 views
9

मैं एंड्रॉयड/जावा में स्थान का एक उपवर्ग की क्रमबद्धता के साथ एक brickwall मार रहागैर serializable माता पिता वर्ग

स्थान के Serializable उपवर्ग serializable नहीं है। मेरे पास FALocation नामक पहला उप-वर्ग है जिसमें कोई आवृत्ति चर नहीं है। मैंने इसे धारावाहिक घोषित कर दिया है।

public class Waypoint extends FALocation implements Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    /* Class variables *******************************************************/ 
    private static int CLASS_VERSION=1; //Used to version parcels 

    /* Instance variables ****************************************************/ 
    private transient String type=DataHelper.PT_TYPE_US; 
    private transient String country; 
    private transient String name=null; 
    private transient String description=null; 
    private transient int elevation = 0; 
    private transient int population = 0; // Afterthought, added to match the DB structure 

    /* Constructors **********************************************************/  
    public Waypoint() { 
     super(); 
    } 

    public Waypoint(double lat, double lon, String name, String description) { 
     super(lat, lon); 
     this.setName(name); 
     this.setDescription(description); 
    } 

    public Waypoint(Location l) { 
     super(l); 
    } 

    public Waypoint(String provider) { 
     super(provider); 
    } 


    /* Implementing serializable */ 
    private void writeObject(java.io.ObjectOutputStream out) throws IOException { 
     Log.v("DroidFA", "Serialising \"%s\" (v%d).", Waypoint.class.getSimpleName(), CLASS_VERSION); 
     out.writeInt(CLASS_VERSION); 

     out.writeObject(type); 
     out.writeObject(country); 
     out.writeObject(name); 
     out.writeObject(description); 
     out.writeInt(elevation); 
     out.writeInt(population); 
    } 

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { 

     int serialClassVersion = in.readInt(); 
     Log.v("DroidFA", "Deserialising \"%s\" (v%d).", Waypoint.class.getSimpleName(),serialClassVersion); 

     type = (String) in.readObject(); 
     country = (String) in.readObject(); 
     name = (String) in.readObject(); 
     description = (String) in.readObject(); 
     elevation = in.readInt(); 
     population = in.readInt(); 
    } 
} 

क्रमबद्धता ठीक काम करता है:

तो मैं एक द्वितीय श्रेणी बुलाया वेपॉइंट है कि इस तरह दिखता है।

Deseriamization पैदा करता followwing अपवाद (पैर वस्तु एक वेपॉइंट शामिल हैं) .:

10-05 13:50:35.259: WARN/System.err(7867): java.io.InvalidClassException: android.location.Location; IllegalAccessException 
10-05 13:50:35.267: WARN/System.err(7867):  at java.io.ObjectInputStream.resolveConstructorClass(ObjectInputStream.java:2010) 
10-05 13:50:35.267: WARN/System.err(7867):  at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2095) 
10-05 13:50:35.267: WARN/System.err(7867):  at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:929) 
10-05 13:50:35.267: WARN/System.err(7867):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2285) 
10-05 13:50:35.278: WARN/System.err(7867):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2240) 
10-05 13:50:35.278: WARN/System.err(7867):  at com.droidfa.navigation.Leg.readObject(Leg.java:262) 
.../... 
+0

ऐसा लगता है कि समस्या कहीं और है। com.droidfa.navigation.Leg.readObject (Leg.java 32062) –

+0

लेग लाइन 262 है: "से = (Waypoint) in.readObject();" जहां वह समस्या वास्तव में निहित है;)। – jmc34

उत्तर

11

यह स्थान क्रमानुसार करने बिल्कुल जरूरी है? हो सकता है कि आप इसे क्षणिक के रूप में चिह्नित कर सकें, और वस्तु को deserializing के बाद गतिशील रूप से प्राप्त कर सकते हैं। (Anyway, from the documentation):

प्रश्न: वर्ग एक Serializable को लागू नहीं करता है, लेकिन एक उपवर्ग बी Serializable लागू करता है, जब बी धारावाहिक है वर्ग ए के क्षेत्र श्रृंखलाबद्ध किया जाएगा?

ए: केवल सीरियलज़ेबल ऑब्जेक्ट्स के फ़ील्ड लिखे गए हैं और पुनर्स्थापित किए गए हैं। ऑब्जेक्ट को केवल तभी बहाल किया जा सकता है जब उसके पास नो-एर्ग कन्स्ट्रक्टर होता है जो गैर-धारावाहिक supertypes के क्षेत्रों को प्रारंभ करेगा। यदि उप-वर्ग के पास सुपरक्लास की स्थिति तक पहुंच है तो वह उस स्थिति को सहेजने और पुनर्स्थापित करने के लिए writeObject और readObject को कार्यान्वित कर सकता है।

इसलिए, यदि उप-वर्ग के पास अपने गैर-धारावाहिक सुपरक्लास (एसएस) के क्षेत्रों तक पहुंच है तो यह serialization को लागू करने के लिए writeObject और readObject प्रोटोकॉल का उपयोग कर सकता है। अन्यथा, ऐसे क्षेत्र होंगे जो क्रमबद्ध करने के लिए संभव नहीं होंगे।

+0

ठीक है, मैं उपखंड से स्थान फ़ील्ड को क्रमबद्ध कर सकता हूं, लेकिन मुद्दा यह है कि यह वैसे भी स्थान को deserialize करने की कोशिश करता है। क्या वैसे भी मैं उपclass से हो रहा है कि रोक सकता है? – jmc34

+0

ठीक है, मेरे पास "छद्म" है जो मेरे स्थान उपखंड को संलग्न वस्तु से serielized है। समस्या का हल किया। धन्यवाद। – jmc34

+0

"मेरे पास" छद्म "है जो मेरे स्थान उपखंड को संलग्न वस्तु से serielized।" हाय मैं इसका सामना कर रहा हूं, क्या आप विस्तृत कर सकते हैं। छद्म का मतलब क्या है? –

1

स्थान की तरह लग रहा सार्वजनिक नहीं है/कोई आर्ग निर्माता की रक्षा की। Subclass में serialization के लिए इसे उपलब्ध कराने के लिए इस तरह के एक कन्स्ट्रक्टर की आवश्यकता है।

http://download.oracle.com/javase/6/docs/api/java/io/Serializable.html का कहना है:

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

और क्रमबद्धता विनिर्देश से शब्दों के साथ एक ही:

एक Serializable वर्ग निम्न करना होगा: ... अपनी पहली nonserializable सुपर क्लास की कोई आर्ग निर्माता के लिए उपयोग किया है

यह समझाएगा कि आपको केवल deserialization में समस्या क्यों है, क्योंकि स्वाभाविक रूप से निर्माता को serialization के दौरान नहीं कहा जाता है।

सुलभ निर्माता के बिना असफल रहने के छोटे उदाहरण:

public class A { 
    public A(String some) {}; 
    private A() {} //as protected or public everything would work 
} 

public class B extends A implements Serializable { 
    public B() { 
     super(""); 
    } 
    //these doesn't really matter 
    //private void writeObject(java.io.ObjectOutputStream out) throws IOException { } 
    //private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { } 
} 

public class BSerializer { 

    public static void main(String ... args) throws Exception { 
     B b = new B(); 

     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     ObjectOutputStream oos = new ObjectOutputStream(baos); 
     oos.writeObject(b); 
     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
     ObjectInputStream ois = new ObjectInputStream(bais); 
     B deserialized = (B) ois.readObject(); //InvalidClassException 
    } 
} 
+0

android.location.Location; IllegalAccessException फेंक दिया जाता है जब कोई प्रोग्राम उस फ़ील्ड या विधि तक पहुंचने का प्रयास करता है जो उस स्थान से पहुंच योग्य नहीं है जहां संदर्भ बनाया गया है। –

+0

स्थान वास्तव में कोई तर्क सार्वजनिक कन्स्ट्रक्टर नहीं है। लेकिन मुझे वहां से कहाँ जाना चाहिए? – jmc34

+0

दुर्भाग्य से आप इसे सीधे क्रमबद्ध नहीं कर सकते हैं। आप कहीं और राज्य को बचाने से ज्यादा कुछ नहीं कर सकते हैं, बचाया राज्य ले सकते हैं और नया स्थान बना सकते हैं (या जो भी इसे बढ़ाता है)। –

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