How does java collection covariance work in a wrapper class?

Viewed 29

I think I have a decent understanding of covariance in java when it comes to List<Base> and List<? extends Base>. I ran into an issue where I was using a wrapper class (LiveData in this case) and it's not working how I expected it to.

I duplicated the issue in a java repl:

import java.util.List;

class Main {  
  public static void main(String args[]) { 
    List<? extends Sub0> test0 = List.of(new C());

    List<Sub1> test1 = List.of(new Sub1());

    List<? extends Base> x = test0;
    x = test1;
    
    Holder<List<? extends Sub0>> ha = new Holder(test0);
    Holder<List<Sub1>> hb = new Holder(test1);

    Holder<List<? extends Base>> z = ha;
    z = hb;
    
  } 
}

interface Base {}

abstract class Sub0 implements Base {}

class Sub1 implements Base {}

class C extends Sub0 {}

class Holder<T> {
  T obj;
  public Holder(T obj){
  this.obj = obj;
  }
}

The x = test0 and x = test1 lines compile as I would expect, but the z = ha and z = hb do not, and I'm not really sure why.

0 Answers
Related