2010-11-19 16 views
21

के साथ जेनिक्स का उपयोग करके मैं जेएसओएन को टाइप टी के ऑब्जेक्ट में जेएसओएन डीकोड करने के लिए उपयोग कर रहा हूं। अनपेक्षित प्रकार:जीएसओएन

java.lang.AssertionError -

public T decode(String json) { 
    Gson gson = new Gson(); 
    return gson.fromJson(json, new TypeToken<T>() {}.getType()); 
} 

हालांकि यह एक अपवाद देता है। में से एक उम्मीद: java.lang.reflect.ParameterizedType, java.lang.reflect.GenericArrayType, लेकिन मिल गया: sun.reflect.generics.reflectiveObjects.TypeVariableImpl, प्रकार टोकन के लिए: टी

मैंने सोचा था कि द्वारा टाइपटेकन I का उपयोग करके टाइप एरर से बचा है।

क्या मैं गलत हूँ?

धन्यवाद

+0

डुप्लिकेट प्रश्न: http://stackoverflow.com/questions/5370768/using-a-generic-type-with-gson –

उत्तर

14

सबसे पहले, मैं यह देखने के लिए ऐसा Gson रैप करने के लिए उपयोगी है असफल।

आपकी समस्या के अनुसार, जेनेरिक प्रकार T के बारे में जानकारी रनटाइम के दौरान उपलब्ध नहीं है। इसे मिटा दिया गया है। यह केवल संकलन समय के दौरान उपलब्ध है। आप new TypeToken<List<String>> जैसे वास्तविक प्रकार के साथ इसे पैरामीटर करना चाहते हैं।

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

वास्तविक प्रकार को पारित करने में सक्षम होने के लिए, आपको उसी चीज को फिर से शुरू करना होगा जैसे TypeToken पहले से ही कर रहा है। और इसका कोई मतलब नहीं है :) बस इसे पुन: उपयोग करें या बस कुछ हेलर क्लास में लपेटे बिना सीधे जीसन का उपयोग करें।

+1

मैं जीएसओएन के वास्तविक उपयोग को उस तंत्र से अलग कर रहा था जो इसका उपयोग करता है। मेरे पास विधि डिकोड (स्ट्रिंग जेसन) के साथ ऑब्जेक्ट डिकोडर इंटरफ़ेस है। इसका मतलब है कि मैं विभिन्न कार्यान्वयन के बीच स्विच कर सकता हूं उदा। जीएसओएन, जैक्सन आदि। फिर मैं तंत्र में निर्भरता को इंजेक्ट करने के लिए गुइस का उपयोग करता हूं। – christophmccann

+3

आपकी सर्वश्रेष्ठ शर्त वास्तव में कक्षा या विधि तर्क के रूप में जीसन के 'टाइपटेकन' का पुन: उपयोग करना है या कम से कम इसे पुन: पेश करना है यदि आप नहीं चाहते हैं कि आपकी एपीआई में तीसरी पार्टी निर्भरता का खुलासा हो। [यह अपाचे लाइसेंस द्वारा खुला स्रोत है] (http://code.google.com/p/google-gson/source/browse/trunk/src/main/java/com/google/gson/reflect/TypeToken.java?spec = svn2 और आर = 2)। [यहां पृष्ठभूमि स्पष्टीकरण] (http://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Gener)। – BalusC

5

मुझे लगता है कि पहले उत्तर वास्तविक समाधान की ओर इशारा नहीं कर रहा है: क्या आप भी, टी के साथ कक्षा उदाहरण गुजरना होगा तो जैसे:

public T decode(String json, Class<T> cls) { 
    Gson gson = new Gson(); 
    return gson.fromJson(json, cls); 
} 

इसका कारण यह है 'टी' यहाँ एक प्रकार चर, नहीं है एक प्रकार का संदर्भ; और केवल कॉम्प्लेयर द्वारा अंतर्निहित कोस्ट जोड़ने और टाइप संगतता को सत्यापित करने के लिए उपयोग किया जाता है। लेकिन यदि आप वास्तविक वर्ग पास करते हैं तो इसका उपयोग किया जा सकता है; और कंपाइलर मेलसमूह के मौके को कम करने के लिए प्रकार संगतता की जांच करेगा।

वैकल्पिक रूप से आप टाइप टोकन में ले सकते हैं और इसे पास कर सकते हैं; लेकिन TypeToken वास्तविक प्रकार के साथ बनाया जाना चाहिए, एक प्रकार चर नहीं; टाइप वैरिएबल यहां थोड़ा उपयोग है। लेकिन अगर आप चीजों को लपेटना चाहते हैं तो आप कॉलर को टाइपटोकन (जो एक जीसन प्रकार है) का उपयोग नहीं करना चाहते हैं।

उसी रैपिंग तंत्र जैक्सन जैसे अन्य libs के साथ काम करेगा, जिसका आपने उल्लेख किया था।

+4

यह पैरामीटरयुक्त वर्गों के लिए काम नहीं करेगा जहां यह प्रश्न सब कुछ है। 'मानचित्र <स्ट्रिंग, ऑब्जेक्ट> .class' जैसी कोई चीज़ नहीं है, केवल 'Map.class'। मेरे उत्तर में टिप्पणी में "पृष्ठभूमि स्पष्टीकरण" लिंक भी देखें। – BalusC

+0

हां, मैं इस मुद्दे के बारे में पूरी तरह से अवगत हूं, यह सिर्फ इतना सवाल नहीं था कि यह एक पैरामीटरयुक्त वर्ग था, इसलिए सरल जवाब पर्याप्त लग रहा था। यह एक दयालु बात है कि जेडीके के पास प्रकार टोकन (प्रकार संदर्भ आदि) के समान नहीं है; प्रत्येक lib/ढांचे को स्वयं परिभाषित करने के लिए)। – StaxMan

0

इस मेरे समाधान JSON पार्सर उपयोग करें और यह टुकड़े

public static <TT> PushObj<TT> fromJSON(String json, Class<TT> classType) 
{ 
    JsonObject jObj = new JsonParser().parse(json).getAsJsonObject(); 
    String type = jObj.get("type").getAsString(); 
    JsonObject job = jObj.get("object").getAsJsonObject(); 
    TT obj = new Gson().fromJson(job, classType); 
    return new PushObj<TT>(type, obj); 
} 

कहाँ वस्तु संरचना है में जगह बनाने वाला था: {स्ट्रिंग: प्रकार, सामान्य वस्तु}

और चर हैं : jObj स्ट्रिंग और नौकरी में पारित की JSONObject के लिए सामान्य वस्तु

तो मैं JSON पार्सर इस्तेमाल किया प्रकार अलग से प्राप्त करने के लिए की JSONObject, और प्रतिबिंब है वस्तु।

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