2016-08-02 7 views
2

У меня есть JSON, который содержит:Gson: Deserialize Json в абстрактный класс

{"timeZone": "America/Los_Angeles"} 

среди многих других ключей, и я десериализация его в java.util.TimeZone. TimeZone - это просто поле в классе, которое я хочу создать с помощью этого json.

Вопрос заключается в том, что TimeZone является абстрактным классом, и он должен быть создан с:

public static synchronized TimeZone getTimeZone(String ID) { 
     return getTimeZone(ID, true); 

, который использует конкретный класс ZoneInfo для создания экземпляра. Однако десериализатор по умолчанию вызывает конструктор TimeZone. Так что я получил:

java.lang.RuntimeException: Failed to invoke public java.util.TimeZone() with no args 

Интересно, как настроить Gson для создания экземпляра TimeZone из приведенного выше JSON?

+0

Вы пытаетесь использовать не абстрактный класс, как SimpleTimeZone? – JAVAC

+0

Id риск сказать, что это невозможно. Сериализатор должен создавать экземпляр для создания выходного значения, а абстрактные классы не могут быть созданы. – Felype

+0

@JAVAC Это из класса библиотеки, который я не могу изменить, к сожалению. –

ответ

5

Вы должны были бы создать что-то вроде Gson TypeAdapter и зарегистрировать его с помощью Gson экземпляра.

Я не знаю, как/будет ли это работать для конкретного формата данных, но вот пример, который я использовал в своих проектах:

public class TimeZoneAdapter extends TypeAdapter<TimeZone> { 
    @Override 
    public void write(JsonWriter out, TimeZone value) throws IOException { 
    out.value(value.getID()); 
    } 

    @Override 
    public TimeZone read(JsonReader in) throws IOException { 
    return TimeZone.getTimeZone(in.nextString()); 
    } 
} 

Вы бы затем зарегистрировать его при создании Gson пример:

GsonBuilder builder = new GsonBuilder(); 
builder.registerTypeAdapter(TimeZone.class, new TimeZoneAdapter()); 

Gson gson = builder.create(); 

Надеюсь, это поможет!

0

Вы должны создать InstanceCreator

private class TimeZoneInstanceCreator implements InstanceCreator<TimeZone> { 
    public TimeZone createInstance(Type type) { 
     return TimeZone.getTimeZone("America/Los_Angeles");; 
    } 
} 

, а затем зарегистрировать его:

gson.registerTypeAdapter(TimeZone.class, new TimeZoneInstanceCreator()); 
+0

Я не думаю, что могу жестко закодировать значение 'America/Los_Angeles'. Это должно быть значение, переданное из json, верно? –

+1

Это неправильно. «InstanceCreator» предназначен только для создания экземпляра. Затем Gson будет следовать своему регулярному потоку, чтобы установить поля из JSON. Это не то, что здесь задают. –