-
-
Notifications
You must be signed in to change notification settings - Fork 14
Polymorphism
Ahmad K. Bawaneh edited this page Dec 24, 2019
·
1 revision
Domino-jackson supports polymorphism by per-class annotations: @JsonTypeInfo
and @JsonSubTypes
. We can have following hierarchy and mappers:
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, visible = true)
@JsonSubTypes({
@Type(value` = MyClassOne.class, name = "childclass"),
@Type(value = MyClassTwo.class, name = "childclass2")})
interface MyBaseInterface {}
class MyClassOne implements MyBaseInterface {}
class MyClassTwo implements MyBaseInterface{}
@JSONMapper
interface ListMapper extends ObjectMapper<List<MyBaseInterface>>
class Foo {
private MyBaseInterface objField;
private Map<Integer, MyBaseInterface> mapField;
}
@JSONMapper
interface FooMapper extends ObjectMapper<Foo>;
The domino-jackson process beans annotated with @JsonTypeInfo
and @JsonSubTypes
and generate all needed serializers and deserializers for subtypes.
There are two limitations here:
- The only supported option for
@JsonTypeInfo
isuse=Id.NAME
. - The base type and all subtypes can NOT be a generic types.
Bounded wildcards
Having polymorphism naturally leads to the need to have wildcards. but bounded wildcards are tricky, here is a working example :
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, visible = true)
@JsonSubTypes({
@Type(value` = MyClassOne.class, name = "childclass"),
@Type(value = MyClassTwo.class, name = "childclass2")})
interface MyBaseInterface {}
class MyClassOne implements MyBaseInterface {}
class MyClassTwo implements MyBaseInterface{}
class Bar {
List<? extends MyBaseInterface> myList;
List<? extends Integer, ? extends MyBaseInterface> myMap;
}
@JSONMapper
interface BarMapper extends ObjectMapper<Bar>{}
But there is some limitations :
- You can not use unbounded wildcards at all
- You can not have
JSONMapper
/JSONReader
/JSONWriter
for type having wildcards or type parameters i.e.
@JSONMapper
interface BarMapper extends ObjectMapper<Bar<Integer>>{} //Valid
interface BarMapper extends ObjectMapper<Bar<Integer, List<Foo>>>{} //Valid
interface BarMapper extends ObjectMapper<Bar<Integer, List<?>>>{} //NOT Valid
interface BarMapper extends ObjectMapper<Bar<? extends Integer>>{} //NOT Valid
interface BarMapper extends ObjectMapper<Bar<List<? extends Integer>>>{} //NOT Valid
interface BarMapper extends ObjectMapper<Bar<T>>{} //NOT Valid
- You can have generic collections with bounded wildcards. The bounds must be referenced in corresponding
@JsonTypeInfo
and@JsonSubType
. Some examples:
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, visible = true)
@JsonSubTypes({
@Type(value` = MyClassOne.class, name = "childclass"),
@Type(value = MyClassTwo.class, name = "childclass2")})
interface MyBaseInterface {}
class MyClassOne implements MyBaseInterface {}
class MyClassTwo implements MyBaseInterface{}
class Bar<T> {
List<? extends T> list;
Map<Integer, ? extends MyBaseInterface> map;
}
@JSONMapper
interface BarMapper extends ObjectMapper<Bar<MyBaseInterface>>{}
- You can not have member fields with type a custom generic class, declared with bounded wildcards i.e.
class Foo<T> {
private List<T> data;
public void setData(List<T> data) {
this.data = data;
}
public List<T> getData() {
return data;
}
}
class Bar<T> {
public List<? extends T> myList; //that is OK
public Foo<T> myFoo; //that is OK
public Foo<? extends Integer> myMember; // WON'T work
public Foo<? extends T> myMember; // WON'T work
}
@JSONMapper
interface BarMapper extends ObjectMapper<Bar<Double>>{}