1. Domino Jackson
  2. Polymorphism

Polymorphism

Domino-jackson supports polymorphism by per-class annotations @JsonTypeInfo and @JsonSubTypes. We can have the following hierarchy and mappers for 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{}

@JSONMapper
interface ListMapper extends ObjectMapper<List<MyBaseInterface>>

class Foo {
      private MyBaseInterface objField;
      private Map<Integer, MyBaseInterface> mapField;
}

@JSONMapper
interface FooMapper extends ObjectMapper<Foo>;
		

Then when a child class extends from that type, it can provide the specific generics types for domino-jackson

			@JSONMapper
public class SampleGenericType extends BaseGenericType<String, Integer> {

    private String field3;

    public String getField3() {
        return field3;
    }

    public void setField3(String field3) {
        this.field3 = field3;
    }
}
		

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 is use=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; // Will not work
        public Foo<? extends T> myMember; // Will not work
    }
    
    @JSONMapper
    interface BarMapper extends ObjectMapper<Bar<Double>>{} 
    		

We are a group of passionate people who love what we do

Donate & Support Us