我正在尝试为我正在使用的JavaFX类型编写TypeAdapterFactory
(不同的属性和可观察对象)。对于ObjectProperty
我可以使用强制转换JsonSerializer/Deserializer
写ParamterizedType
,然后获取ActualTypeArguments
。
这是我用来实现此目的的代码:
public class ObjectPropertySerializer implements JsonSerializer<ObjectProperty>, JsonDeserializer<ObjectProperty> {
@Override
public ObjectProperty deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Type objectType = ((ParameterizedType)typeOfT).getActualTypeArguments()[0];
return new SimpleObjectProperty(new GsonBuilder().create().fromJson(json, objectType));
}
@Override
public JsonElement serialize(ObjectProperty src, Type typeOfSrc, JsonSerializationContext context) {
Type objectType = ((ParameterizedType)typeOfSrc).getActualTypeArguments()[0];
return new GsonBuilder().create().toJsonTree(src.getValue(), objectType);
}
}
但是,由于嵌套类/对象和直接序列化,我还需要使用TypeAdapterFactory
,这在使用GsonBuilder
将序列化程序直接注册到.registerTypeAdapter()
时无效。
这是我工厂的代码(其他属性已经有效):
public class JFXGsonAdapterFactory implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if ( BooleanProperty.class.isAssignableFrom(type.getRawType()) ) {
return (TypeAdapter<T>) new BooleanPropertyAdapter();
}
else if ( DoubleProperty.class.isAssignableFrom(type.getRawType()) ) {
return (TypeAdapter<T>) new DoublePropertyAdapter();
}
else if (IntegerProperty.class.isAssignableFrom(type.getRawType()) ) {
return (TypeAdapter<T>) new IntegerPropertyAdapter();
}
else if (ObjectProperty.class.isAssignableFrom(type.getRawType()) ) {
return (TypeAdapter<T>) new ObjectPropertyAdapter(gson);
}
else if ( StringProperty.class.isAssignableFrom(type.getRawType()) ) {
return (TypeAdapter<T>) new StringPropertyAdapter();
}
else {
return null;
}
}
}
我无法在此处返回序列化程序/反序列化程序接口的实现,但需要使用扩展TypeAdapter
的适配器类。
以下是TypeAdapter
的{{1}}实施:
ObjectProperty
但是我不知道如何在TypeAdapter中获取ObjectProperty的泛型类型,我也不知道如何从TypeToken中获取它(因为我可以从工厂将它传递给适配器)。
问题摘要:
1)如何将public class ObjectPropertyAdapter<T> extends TypeAdapter<ObjectProperty> {
private Gson gson;
TypeAdapter<JsonElement> elementAdapter;
public ObjectPropertyAdapter( Gson gson ) {
this.gson = gson;
elementAdapter = gson.getAdapter(JsonElement.class);
}
@Override
public void write(JsonWriter out, ObjectProperty value) throws IOException {
if ( value == null ) {
out.nullValue();
} else {
JsonElement jsonElement = gson.toJsonTree(value.get());
elementAdapter.write(out, jsonElement);
}
}
@Override
public ObjectProperty read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
} else {
// Read
return null; // tmp
}
}
}
的实现转换为TypeAdapter
或
2)我如何获得通用类型,例如TypeToken中的ObjectProperty?
或
3)我需要做一些完全不同的事情来实现这个目标吗?
答案 0 :(得分:3)
1)你不能。 JsonSerializer
和JsonDeserializer
是旧转换方式。新应用程序应使用TypeAdapter
,它具有功能超集。
2)假设您的意思是JavaFX的ObjectProperty<T>
,并且您想要提取T&C的课程。
您可以使用Type
轻松访问TypeToken
内的TypeToken#getType()
。
我将给出List<String>
的示例,这个想法是相同的,但很容易测试。
TypeToken<List<String>> typeToken = new TypeToken<List<String>>(){};
System.out.println("typeToken.getRawType() = " + typeToken.getRawType());
Type type = typeToken.getType();
System.out.println("typeToken.getType() = " + type);
if (type instanceof ParameterizedType) {
Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
System.out.println("typeArguments = " + Arrays.toString(typeArguments));
}
输出结果:
typeToken.getRawType() = interface java.util.List
typeToken.getType() = java.util.List<java.lang.String>
typeArguments = [class java.lang.String]
3)我想你差不多了。 ;-)啊,对于TypeAdapter
,您不会考虑JsonObject
或JsonElement
(DOM样式),但您可以动态构建对象或JSON表示(流式)。
另外,在你的问题中你说
但是由于嵌套,我还需要使用TypeAdapterFactory 类/对象和直接序列化,当不起作用时 使用将注册表直接注册到GsonBuilder .registerTypeAdapter()。
也许您需要使用GsonBuilder#registerTypeHierarchyAdapter()
并查找这些嵌套类。这取决于您的问题详情。