2013-04-21 4 views
6

के बजाय LinkedHashMap लौटाएं मैं जीएसएन को EnumMap ऑब्जेक्ट वापस करने में सक्षम बनाना चाहता हूं। मैं निम्नलिखित कोड का उपयोगजीएसओएन से जेसन वापस एनमैप

package sandbox; 

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 
import java.util.EnumMap; 
import java.util.Map; 

/** 
* 
* @author yccheok 
*/ 
public class Sandbox { 

    public static void main(String[] args) throws InterruptedException {  
     testGson(); 
    } 

    public static enum Country { 
     Malaysia, 
     UnitedStates 
    } 

    public static void testGson() { 
     Map<Country, String> enumMap = new EnumMap<Country, String>(Country.class); 
     enumMap.put(Country.Malaysia, "RM"); 
     enumMap.put(Country.UnitedStates, "USD"); 
     Gson gson = new Gson(); 
     String string = gson.toJson(enumMap); 
     System.out.println("toJSon : " + string); 
     enumMap = gson.fromJson(string, new TypeToken<EnumMap<Country, String>>(){}.getType()); 
     System.out.println("fromJSon : " + enumMap); 
     System.out.println("fromJSon : " + enumMap.getClass()); 
    } 
} 

हालांकि, मैं निम्नलिखित

toJSon : {"Malaysia":"RM","UnitedStates":"USD"} 
fromJSon : {Malaysia=RM, UnitedStates=USD} 
fromJSon : class java.util.LinkedHashMap 

भले ही मैं विशिष्ट करने के लिए इस्तेमाल किया था new TypeToken<EnumMap<Country, String>>(){}.getType() हो रही है मैं चाहता हूँ EnumMap बजाय LinkedHashMap

मैं कैसे कर सकते हैं EnumMap वापस करने के लिए जीसन?

उत्तर

9

यहां तक ​​कि एक प्रकार के टोकन के साथ, जीसन केवल उन वर्गों में डेटा को विलुप्त कर सकता है जिनमें डिफ़ॉल्ट कन्स्ट्रक्टर है। और EnumMap में कोई नहीं है (इसे enum के प्रकार के साथ तत्काल करने की आवश्यकता है कि उसके तत्व मिलेंगे)।

यह इंटरफ़ेस कार्यान्वित किया जाता है एक वर्ग के उदाहरण है कि एक नो-args निर्माता को परिभाषित नहीं करता बनाने के लिए: इस समस्या को हल सबसे आसान तरीका है परिभाषित करने और एक InstanceCreator उपयोग करने के लिए है। यदि आप कक्षा को संशोधित कर सकते हैं, तो आपको इसके बजाय एक निजी, या सार्वजनिक नो-Args कन्स्ट्रक्टर जोड़ना चाहिए। हालांकि, पुस्तकालय वर्गों के लिए यह संभव नहीं है, जैसे कि जेडीके कक्षाएं, या एक तृतीय-पक्ष लाइब्रेरी जिसमें आपके पास स्रोत-कोड नहीं है। ऐसे मामलों में, आपको कक्षा के लिए एक उदाहरण निर्माता परिभाषित करना चाहिए। इस इंटरफ़ेस के कार्यान्वयन GsonBuilder.registerTypeAdapter (टाइप, ऑब्जेक्ट) विधि के साथ पंजीकृत होना चाहिए इससे पहले कि जीसन उनका उपयोग कर सके।

Heres कुछ उदाहरण कोड:

InstanceCreator:

class EnumMapInstanceCreator<K extends Enum<K>, V> implements 
     InstanceCreator<EnumMap<K, V>> { 
    private final Class<K> enumClazz; 

    public EnumMapInstanceCreator(final Class<K> enumClazz) { 
     super(); 
     this.enumClazz = enumClazz; 
    } 

    @Override 
    public EnumMap<K, V> createInstance(final Type type) { 
     return new EnumMap<K, V>(enumClazz); 
    } 
} 

टेस्ट कोड:

final Gson gson = new GsonBuilder().registerTypeAdapter(
     new TypeToken<EnumMap<Country, String>>() { 
     }.getType(), 
     new EnumMapInstanceCreator<Country, String>(Country.class)) 
     .create(); 

final Map<Country, String> enumMap = new EnumMap<Country, String>(
     Country.class); 
enumMap.put(Country.Malaysia, "RM"); 
enumMap.put(Country.UnitedStates, "USD"); 
String string = gson.toJson(enumMap); 
System.out.println("toJSon : " + string); 

final Map<Country, String> reverseEnumMap = gson.fromJson(string, 
     new TypeToken<EnumMap<Country, String>>() { 
     }.getType()); 
System.out.println("fromJSon (Class): " + reverseEnumMap.getClass()); 
System.out.println("fromJSon : " + reverseEnumMap); 
+0

थोड़े अजीब है, मैं अपने कोड वास्तव में उपयोग करते हैं, लेकिन मैं अभी भी हो रही है LinkedHashMap मेरी तरफ। मैं जीसन-2.1 का उपयोग कर रहा हूँ। फर्क पड़ता है क्या? –

+3

क्षमा करें। नवीनतम जीसन 2.2.3 का उपयोग सही काम करता है। –

+1

@CheokYanCheng GSON 2.2.3 का उपयोग कर यह आपके लिए बिना किसी कोड परिवर्तन के बॉक्स के बाहर काम करता है? –

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