2013-10-18 3 views
5

मेरे जावा एप्लिकेशन पर संदर्भित नहीं करता है, मैंने दो वर्गों को परिभाषित किया है, जिन्हें A और B कहा जाता है, जहां BA की आंतरिक श्रेणी है। दोनों GSON के साथ इस वस्तु, getSomeCalculationValue ठीक काम करता है serializing पहले serializableजीएसओएन बाहरी कक्षा

public class A implements Serializable { 

    int attrParent; 
    List<B> items = new ArrayList<B>(); 

    public void setAttrParent(int attrParent) { 
     this.attrParent = attrParent; 
    } 

    public int getAttrParent() { 
     return attrParent; 
    } 

    public class B implements Serializable { 

     private int attr; 

     public void setAttr(int attr) { 
      this.attr = attr; 
     } 

     public int getAttr() { 
      return attr; 
     } 

     public int getSomeCalculationValue() { 
      return this.attr * A.this.attrParent; // Problems occurs here 
     } 

    } 
} 

के रूप में परिभाषित कर रहे हैं। लेकिन, धारावाहिक और deserializing के बाद, getSomeCalculationValueNullPointerException के साथ विफल रहता है।

ऐसा इसलिए होता है क्योंकि आंतरिक वर्ग B में बाहरी वर्ग A का संदर्भ नहीं है, इसलिए A.this विफल रहता है।

क्या कोई जानता है कि मैं इसे कैसे हल कर सकता हूं, जो इस ऑब्जेक्ट को deserializing करते समय आंतरिक संदर्भ को बाहरी बहाल कर रहा है?

+0

कृपया अपना क्रमबद्धरण और deserialization प्रक्रिया के साथ ही नमूना जीसन दिखाएं। मुझे नहीं लगता कि आपको यहां 'Serializable' क्यों चाहिए। –

उत्तर

6

रूप Gson प्रलेखन कहते हैं:

Gson काफी आसानी से स्थिर नेस्टेड वर्गों को क्रमानुसार कर सकते हैं।

जीसन स्थिर घोंसला वाले वर्गों को भी बेकार कर सकता है। हालांकि, जीसन अपने आंतरिक नो-Args कन्स्ट्रक्टर के साथ स्वचालित आंतरिक वर्गों को स्वचालित रूप से deserialize नहीं कर सकते हैं कन्स्ट्रक्टर को ऑब्जेक्ट के संदर्भ की भी आवश्यकता है जो deserialization के समय उपलब्ध नहीं है। आप या तो आंतरिक कक्षा स्थिर या द्वारा कस्टम इंस्टेंस क्रिएटर प्रदान करके इस समस्या को हल कर सकते हैं। के बाद से अपने विधि getSomeCalculationValue में बाहरी वर्ग के लिए एक संदर्भ की जरूरत है

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

public class ADeserializer implements JsonDeserializer<A> { 
    public A deserialize(JsonElement json, Type typeOfT, 
     JsonDeserializationContext context) throws JsonParseException { 

    A a = new A(); 
    a.attrParent = json.getAsJsonObject().get("attrParent").getAsInt(); 
    JsonArray ja = json.getAsJsonObject().get("items").getAsJsonArray(); 
    for(JsonElement e: ja){ 
     B b = a.new B(); 
     b.setAttr(e.getAsJsonObject().get("attr").getAsInt()); 
     a.items.add(b); 
    } 
    return a; 
    } 

} 

और यह मैं इसे कैसे उपयोग करते हैं:

public class Q19449761 { 

    public static void main(String[] args) { 

     A a = new A(); 
     a.setAttrParent(3); 
     B b = a.new B(); 
     b.setAttr(10); 
     a.items.add(b); 
     System.out.println("Before serializing: " + a.items.get(0).getSomeCalculationValue()); 

     Gson g = new Gson(); 

     String json = g.toJson(a, A.class); 
     System.out.println("JSON string: " + json); 

     A test2 = g.fromJson(json, A.class); 

     try { 
      System.out.println("After standard deserialization: " +test2.items.get(0).getSomeCalculationValue()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     GsonBuilder builder = new GsonBuilder(); 
     builder.registerTypeAdapter(A.class, new ADeserializer()); 

     A test3 = builder.create().fromJson(json, A.class); 

     System.out.println("After custom deserialization: " + test3.items.get(0).getSomeCalculationValue()); 

    } 

} 

और ये मेरे निष्पादन है:

Before serializing: 30 
JSON string: {"attrParent":3,"items":[{"attr":10}]} 
java.lang.NullPointerException 
    at stackoverflow.questions.q19449761.A$B.getSomeCalculationValue(A.java:32) 
    at stackoverflow.questions.q19449761.Q19449761.main(Q19449761.java:26) 
After custom deserialization: 30 

दो अंतिम नोट:

  1. आप की जरूरत नहीं है Serializable इंटरफेस को कार्यान्वित करें, जेएसओएन के पास जा के साथ कुछ भी सामान्य नहीं है v serialization
  2. मेरा deserializer शून्य मामलों प्रबंधन की कमी है, आप शून्य JSON या शून्य क्षेत्रों के लिए पूरा करना चाहिए।
+0

'स्थिर आंतरिक' शब्दों में एक विरोधाभास है। – EJP

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