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));
}
};
}
}
This is my attempted TypeAdapterFactory for Guava's BiMap class. I am essentially delegating to Gson's MapTypeAdapterFactory. However, with this, a type like BiMap<UUID, String> has its keys deserialized as a String. I know this since I get a ClassCastException whenever I try to access a value with a UUID. I have also added my own UUID TypeAdapter but it still persists.
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));
}
};
}
}
I believe I found the issue, it was this line:
TypeAdapter<Map<K, V>> mapTypeAdapter = gson.getAdapter(new TypeToken<Map<K, V>>() {});
The above is the updated code. Any comments/improvements welcome.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.