Java - What is the output: Upper-Bounded Wildcards Assignment?

Question

What is the output of the following code?

public class Main {
  public static void main(String[] args) {
    Wrapper<Integer> intWrapper = new Wrapper<Integer>(new Integer(10));
    Wrapper<? extends Number> numberWrapper = intWrapper; 
   
    Number a = 0;
    numberWrapper.set(a); // A compile-time error
    numberWrapper.set(new Double(1.20)); // A compile-time error
    
    System.out.println(sum(a,numberWrapper));
    
    
  }
  static double sum(Wrapper<? extends Number> n1, Wrapper<? extends Number> n2){
    Number num1 = n1.get();
    Number num2 = n2.get();
    double sum = num1.doubleValue() + num2.doubleValue();
    return sum;
}
}

class Wrapper<T> {
  private T ref;

  public Wrapper(T ref) {
    this.ref = ref;
  }

  public T get() {
    return ref;
  }

  public void set(T a) {
    this.ref = a;
  }
}


Click to view the answer

numberWrapper.set(a); // A compile-time error
numberWrapper.set(new Double(1.20)); // A compile-time error
    
System.out.println(sum(a,numberWrapper));// A compile-time error

Note

numberWrapper is <? extends Number>, it can refer to anything that is a subtype of the Number class.

Since Integer is a subclass of Number, the assignment of intWrapper to numberWrapper is allowed.

numberWrapper = intWrapper; //OK
   

When using the set() method on numberWrapper, the compiler cannot make sure at compile time that numberWrapper is a type of Integer or Double.