2011-10-09 8 views
11

का उपयोग कर अपरिवर्तनीय सूची का निराकरण करना मैं कुछ अपरिवर्तनीय संग्रह का उपयोग कर रहा हूं और मुझे उत्सुकता है कि उन्हें जीसन का उपयोग करके deserialize कैसे करें। जैसा कि किसी ने उत्तर नहीं दिया और मुझे स्वयं समाधान मिला है, मैं सवाल को सरल बना रहा हूं और अपना उत्तर प्रस्तुत कर रहा हूं।जीएसन

  • एक भी Deserializer कैसे लिखने के लिए सभी ImmutableList<XXX> के लिए काम:

    मैं दो समस्या नहीं थी?

  • सभी ImmutableList<XXX> के लिए इसे कैसे पंजीकृत करें?

उत्तर

10

अद्यतन: नहीं है https://github.com/acebaggins/gson-serializers जो कई अमरूद संग्रह शामिल हैं:

  • ImmutableList
  • ImmutableSet
  • ImmutableSortedSet
  • ImmutableMap
  • ImmutableSortedMap

कैसे एक भी deserializer सभी ImmutableList के लिए काम लिखने के लिए?

विचार सरल है, को बदलने से पारित कर दिया Type एक TypeList<T> का प्रतिनिधित्व करने में एक ImmutableList<T> का प्रतिनिधित्व करने वाले एक List बना सकते हैं और यह एक ImmutableList कन्वर्ट करने के लिए Gson की क्षमता में निर्माण का उपयोग करें।

class MyJsonDeserializer implements JsonDeserializer<ImmutableList<?>> { 
    @Override 
    public ImmutableList<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { 
     final Type type2 = ParameterizedTypeImpl.make(List.class, ((ParameterizedType) type).getActualTypeArguments(), null); 
     final List<?> list = context.deserialize(json, type2); 
     return ImmutableList.copyOf(list); 
    } 
} 

एक से अधिक जावा लाइब्रेरीज मैं उपयोग में ParameterizedTypeImpl वर्ग हैं, लेकिन उनमें से कोई सार्वजनिक उपयोग के लिए इरादा है। मैंने इसे sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl के साथ परीक्षण किया।

कैसे सब ImmutableList के लिए यह रजिस्टर करने के लिए?

हिस्सा मामूली बात है यही कारण है, रजिस्टर करने के लिए पहला तर्क java.lang.reflect.Type है जो मुझे ParameterizedType उपयोग करते हुए, जहां बस Class है काम का उपयोग करने को गुमराह:

final Gson gson = new GsonBuilder() 
    .registerTypeAdapter(ImmutableList.class, myJsonDeserializer) 
    .create(); 
+0

क्या हम पैरामीटरेट टाइपटाइम्पल का उपयोग करने से बच सकते हैं? उदाहरण के लिए smth का उपयोग करके: अंतिम सूची सूची = context.deserialize (json, list.class); –

+0

@Alexander Bezrodniy: मुझे डर है, यह संभव नहीं है। आप 'TypeAdapter >' का उपयोग कर इसे से बच सकते हैं, लेकिन फिर आपको कुछ अन्य बॉयलरप्लेट कोड लिखना होगा: 1।'कार्यान्वयन' लागू करें भले ही डिफ़ॉल्ट कार्यान्वयन पर्याप्त होगा, 2. 'read' में' null' के साथ सौदा करें। यह सब कुछ कम स्तर की सामग्री है। – maaartinus

+0

मुझे लगता है कि अब मैं आपका प्रश्न समझता हूं। आप जेनेरिक छोड़ नहीं सकते; उनके बिना सूची सामग्री ठीक से deserialized नहीं किया जा सकता है। – maaartinus

2

@maaartinus पहले से ही दूसरे प्रश्न कवर, तो मैं 'पोस्ट करूँगा पहला सवाल के लिए एक पूरक अमरूद आधारित समाधान जो ParametrizedTypeImpl

public final class ImmutableListDeserializer implements JsonDeserializer<ImmutableList<?>> { 
    @Override 
    public ImmutableList<?> deserialize(final JsonElement json, final Type type, 
             final JsonDeserializationContext context) 
     throws JsonParseException { 
    final Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments(); 
    final Type parameterizedType = listOf(typeArguments[0]).getType(); 
    final List<?> list = context.deserialize(json, parameterizedType); 
    return ImmutableList.copyOf(list); 
    } 

    private static <E> TypeToken<List<E>> listOf(final Type arg) { 
    return new TypeToken<List<E>>() {} 
     .where(new TypeParameter<E>() {}, (TypeToken<E>) TypeToken.of(arg)); 
    } 
} 
7

एक और इम्प की आवश्यकता नहीं है ParameterizedTypeImpl के बिना पेंशनेशन

@Override 
public ImmutableList<?> deserialize(final JsonElement json, final Type type, final JsonDeserializationContext context) throws JsonParseException { 
    @SuppressWarnings("unchecked") 
    final TypeToken<ImmutableList<?>> immutableListToken = (TypeToken<ImmutableList<?>>) TypeToken.of(type); 
    final TypeToken<? super ImmutableList<?>> listToken = immutableListToken.getSupertype(List.class); 
    final List<?> list = context.deserialize(json, listToken.getType()); 
    return ImmutableList.copyOf(list); 
}