2013-09-05 10 views
43

Gson user guide बताता है कि हमें किसी भी वर्ग के लिए सही तरीके से जीसन के साथ काम करने के लिए डिफ़ॉल्ट नो-Args कन्स्ट्रक्टर को परिभाषित करना चाहिए। Gson के InstanceCreator क्लास पर javadoc में और भी अधिक कहा गया है कि अगर हम कक्षा के डिफॉल्ट कन्स्ट्रक्टर के लापता होने के उदाहरण को deserialize करने का प्रयास करते हैं तो हम अपवाद फेंक दिए जाएंगे और ऐसे मामलों में InstanceCreator का उपयोग करना चाहिए। हालांकि, मैंने किसी भी परेशानी के बिना डिफ़ॉल्ट कन्स्ट्रक्टर की कमी वाले वर्ग और सीरियलाइजेशन और deserialization काम दोनों के साथ जीसन का उपयोग करने की कोशिश की है।क्या जीएसन के लिए डिफॉल्ट नो-Args कन्स्ट्रक्टर अनिवार्य है?

यहां deserializaiton के लिए कोड का टुकड़ा है। बिना गैर args निर्माता एक वर्ग:

public class Mushroom { 
    private String name; 
    private double diameter; 

    public Mushroom(String name, double diameter) { 
     this.name = name; 
     this.diameter = diameter; 
    } 

    //equals(), hashCode(), etc. 
} 

और एक परीक्षण:

@Test 
public void deserializeMushroom() { 
    assertEquals(
      new Mushroom("Fly agaric", 4.0), 
      new Gson().fromJson(
        "{name:\"Fly agaric\", diameter:4.0}", Mushroom.class)); 
} 

जो ठीक काम करता है।

तो मेरा सवाल है: क्या मैं वास्तव में डिफ़ॉल्ट कन्स्ट्रक्टर रखने की आवश्यकता के बिना जीसन का उपयोग कर सकता हूं या कोई परिस्थिति नहीं है जब यह काम नहीं करेगी?

उत्तर

70

जीसन 2.3.1 के रूप में।

क्या Gson प्रलेखन कहते हैं की परवाह किए बिना, यदि आपका वर्ग एक नो-args निर्माता नहीं है और आप किसी भी InstanceCreater वस्तुओं पंजीकृत नहीं किया है, तो यह पैदा करेगा एक ObjectConstructor एक UnsafeAllocator जो का उपयोग करता है के साथ (जो आपके वस्तु का निर्माण) अपनी कक्षा के उदाहरण बनाने के लिए कक्षा sun.misc.Unsafe की विधि प्राप्त करने के प्रतिबिंब।

यह Unsafe class नो-Args कन्स्ट्रक्टर की कमी के आसपास चला जाता है और many other dangerous uses है। allocateInstance राज्य

एक उदाहरण आवंटित करें लेकिन किसी भी निर्माता को न चलाएं। कक्षा शुरू करता है यदि यह अभी तक नहीं हुआ है।

इसलिए इसे वास्तव में एक निर्माता की आवश्यकता नहीं है और आपके दो तर्क कन्स्ट्रक्टर के आसपास जाना होगा। कुछ उदाहरण here देखें।

आप नो args निर्माता है, तो Gson डिफ़ॉल्ट Constructor कि

yourClassType.getDeclaredConstructor(); // ie. empty, no-args 

मेरे 2 सेंट फोन करके एक ObjectConstructor जो का उपयोग करता है का उपयोग करेगा: एक नहीं के साथ क्या Gson कहते पालन करें और अपने कक्षाएं बना -र्ग निर्माता या InstanceCreator पंजीकृत करें। Unsafe का उपयोग करके आप खुद को खराब स्थिति में पा सकते हैं।

+0

क्या होगा यदि मेरे पास एक डिफ़ॉल्ट कन्स्ट्रक्टर है जो मेरे अंतिम सदस्य को शून्य पर सेट करता है, लेकिन इस सदस्य के लिए कोई सेटटर नहीं है? क्या यह एक समझदार समाधान है? –

+1

@ thomas.mc.work जीसन सीधे प्रतिबिंब (और संभावित रूप से कुछ असुरक्षित काम) के माध्यम से फ़ील्ड सेट करने में सक्षम होंगे और आप इसे गेटटर (या सीधे क्षेत्र के माध्यम से पुनर्प्राप्त कर सकते हैं। मैं इस डिज़ाइन की अनुशंसा नहीं करता हूं। –

+0

I लाइब्रेरी जैक्सन के साथ 'अंतिम' समस्या के लिए एक अच्छा समाधान मिला है जिसे यहां वर्णित किया गया है: http://stackoverflow.com/a/11838468/2854723 –

1

Jackson पुस्तकालय में एक अच्छा समाधान के रूप में यहाँ वर्णित है:

https://stackoverflow.com/a/11838468/2854723

बिंदु Mix-Ins feature जब तर्क के साथ निर्माता का उपयोग कर जो JSON फ़ील्ड का उपयोग करने के माध्यम से serializer बताने के लिए है।

यदि वह इकाई बाहरी पुस्तकालय का हिस्सा है तो आप Creator feature के साथ "दूरस्थ एनोटेट" कर सकते हैं।

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