Home > database >  Java Generic Type flexibility with subtype assignment
Java Generic Type flexibility with subtype assignment

Time:05-11

I have the following structure. A parent class:

public class MyTree<E extends MyTree<E>>{
   List<E> children;

   public MyTree(List<E> ls){
      this.children = ls;
   }
   
   public void insert(E t){
     this.children.add(t);
   }
}

a child class:

public class SpecTree<E> extends MyTree<SpecTree<E>>{
   private E value;

   public SpecTree(E value){
      super(new ArrayList<>());
      this.value = value;
   }
}

Now from main, I want to insert a tree into another tree.

SpecTree<Number> st = new SpecTree<>(0);
st.insert(new SpecTree<Integer>(2));      //incompatible type error

The SpecTree must be able to accept new children with values that are subtype of the current tree. For example, I should be able to insert a SpecTree<Integer> into SpecTree<Number>.

Is it possible to do without changing the structure of code and changing only the type parameters?

CodePudding user response:

The error occurs because insert expects SpecTree<Number>, but we are giving it SpecTree<Integer>.

According to PECS, insert would be able to take both SpecTree<Number> and SpecTree<Integer> if it had took a SpecTree<? extends Number>. A producer of integers is a consumer of numbers.

That means changing E to SpecTree<? extends E>:

public void insert(E t)

Therefore:

class SpecTree<E> extends MyTree<SpecTree<? extends E>>

However, now the type argument SpecTree<? extends E> does not fit the bound specified in MyTree, which is E extends MyTree<T>, so we change that too:

class MyTree<E extends MyTree<? extends E>>
  • Related