#java #gson #uuid
#java #gson #uuid
Вопрос:
public class BiMapTypeAdapterFactory implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
if (typeToken.getRawType() != BiMap.class
|| !(type instanceof ParameterizedType)) {
return null;
}
return (TypeAdapter<T>) newBiMapAdapter(gson);
}
private <K, V> TypeAdapter<BiMap<K, V>> newBiMapAdapter(Gson gson) {
TypeAdapter<Map<K, V>> mapTypeAdapter = gson.getAdapter(new TypeToken<Map<K, V>>() {});
return new TypeAdapter<BiMap<K, V>>() {
public void write(JsonWriter out, BiMap<K, V> value) throws IOException {
mapTypeAdapter.write(out, value);
}
public BiMap<K, V> read(JsonReader in) throws IOException {
return HashBiMap.create(mapTypeAdapter.read(in));
}
};
}
}
Это моя попытка TypeAdapterFactory для класса BiMap от Guava. По сути, я делегирую Gson MapTypeAdapterFactory. Однако при этом тип, подобный BiMap<UUID, String>, десериализует свои ключи в виде строки. Я знаю это, так как я получаю ClassCastException всякий раз, когда я пытаюсь получить доступ к значению с помощью UUID. Я также добавил свой собственный UUID TypeAdapter, но он все еще сохраняется.
Ответ №1:
public class BiMapTypeAdapterFactory implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
if (typeToken.getRawType() != BiMap.class
|| !(type instanceof ParameterizedType)) {
return null;
}
TypeToken<?> mapType = TypeToken.getParameterized(
Map.class, ((ParameterizedType) type).getActualTypeArguments());
TypeAdapter mapTypeAdapter = gson.getAdapter(mapType);
return (TypeAdapter<T>) newBiMapAdapter(mapTypeAdapter);
}
private <K, V> TypeAdapter<BiMap<K, V>> newBiMapAdapter(TypeAdapter<Map<K, V>> mapTypeAdapter) {
return new TypeAdapter<BiMap<K, V>>() {
public void write(JsonWriter out, BiMap<K, V> value) throws IOException {
mapTypeAdapter.write(out, value);
}
public BiMap<K, V> read(JsonReader in) throws IOException {
return HashBiMap.create(mapTypeAdapter.read(in));
}
};
}
}
Я полагаю, что нашел проблему, это была эта строка:
TypeAdapter<Map<K, V>> mapTypeAdapter = gson.getAdapter(new TypeToken<Map<K, V>>() {});
Приведенный выше обновленный код. Любые комментарии / улучшения приветствуются.