mirror of
https://github.com/fankes/moshi.git
synced 2025-10-20 00:19:21 +08:00
Fix ClassJsonAdapter to handle ParameterizedTypes. (#422)
This commit is contained in:
committed by
Jesse Wilson
parent
834a401122
commit
3b89cf1fcb
@@ -21,6 +21,7 @@ import java.lang.annotation.Annotation;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -46,8 +47,10 @@ final class ClassJsonAdapter<T> extends JsonAdapter<T> {
|
|||||||
public static final JsonAdapter.Factory FACTORY = new JsonAdapter.Factory() {
|
public static final JsonAdapter.Factory FACTORY = new JsonAdapter.Factory() {
|
||||||
@Override public @Nullable JsonAdapter<?> create(
|
@Override public @Nullable JsonAdapter<?> create(
|
||||||
Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||||
if (!(type instanceof Class)) return null;
|
if (!(type instanceof Class || type instanceof ParameterizedType)) {
|
||||||
Class<?> rawType = (Class<?>) type;
|
return null;
|
||||||
|
}
|
||||||
|
Class<?> rawType = Types.getRawType(type);
|
||||||
if (rawType.isInterface() || rawType.isEnum()) return null;
|
if (rawType.isInterface() || rawType.isEnum()) return null;
|
||||||
if (Util.isPlatformType(rawType) && !Types.isAllowedPlatformType(rawType)) {
|
if (Util.isPlatformType(rawType) && !Types.isAllowedPlatformType(rawType)) {
|
||||||
throw new IllegalArgumentException("Platform "
|
throw new IllegalArgumentException("Platform "
|
||||||
@@ -74,7 +77,7 @@ final class ClassJsonAdapter<T> extends JsonAdapter<T> {
|
|||||||
|
|
||||||
ClassFactory<Object> classFactory = ClassFactory.get(rawType);
|
ClassFactory<Object> classFactory = ClassFactory.get(rawType);
|
||||||
Map<String, FieldBinding<?>> fields = new TreeMap<>();
|
Map<String, FieldBinding<?>> fields = new TreeMap<>();
|
||||||
for (Type t = rawType; t != Object.class; t = Types.getGenericSuperclass(t)) {
|
for (Type t = type; t != Object.class; t = Types.getGenericSuperclass(t)) {
|
||||||
createFieldBindings(moshi, t, fields);
|
createFieldBindings(moshi, t, fields);
|
||||||
}
|
}
|
||||||
return new ClassJsonAdapter<>(classFactory, fields).nullSafe();
|
return new ClassJsonAdapter<>(classFactory, fields).nullSafe();
|
||||||
|
@@ -444,6 +444,23 @@ public final class ClassJsonAdapterTest {
|
|||||||
assertThat(fromJson.zipCode).isEqualTo("94043");
|
assertThat(fromJson.zipCode).isEqualTo("94043");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final class Box<T> {
|
||||||
|
final T data;
|
||||||
|
|
||||||
|
Box(T data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void parameterizedType() throws Exception {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
JsonAdapter<Box<Integer>> adapter = (JsonAdapter<Box<Integer>>) ClassJsonAdapter.FACTORY.create(
|
||||||
|
Types.newParameterizedTypeWithOwner(ClassJsonAdapterTest.class, Box.class, Integer.class),
|
||||||
|
NO_ANNOTATIONS, moshi);
|
||||||
|
assertThat(adapter.fromJson("{\"data\":5}").data).isEqualTo(5);
|
||||||
|
assertThat(adapter.toJson(new Box<>(5))).isEqualTo("{\"data\":5}");
|
||||||
|
}
|
||||||
|
|
||||||
private <T> String toJson(Class<T> type, T value) throws IOException {
|
private <T> String toJson(Class<T> type, T value) throws IOException {
|
||||||
@SuppressWarnings("unchecked") // Factory.create returns an adapter that matches its argument.
|
@SuppressWarnings("unchecked") // Factory.create returns an adapter that matches its argument.
|
||||||
JsonAdapter<T> jsonAdapter = (JsonAdapter<T>) ClassJsonAdapter.FACTORY.create(
|
JsonAdapter<T> jsonAdapter = (JsonAdapter<T>) ClassJsonAdapter.FACTORY.create(
|
||||||
|
Reference in New Issue
Block a user