2

Here is a class

public static class Base {
  public int b1;
}

Here is a Consumer function 

public static Consumer<Base> consumer = (t) -> {
System.out.println("" + t.b1);};

This is the calling sequence:   

Base base1 = new Base();
consumer.accept(base1);

This is what I expect.

If I change the consumer to accept extensions of Base: 

public static Consumer<? extends Base> consumer = (t) -> {
  System.out.println("" + t.b1);};

Then the same calling sequence doesn't compile. The compiler complaining that the capture of the consumer is not applicable to argument Base

Base surely extends Base??

If instead of a Consumer I define a method: 

static <T extends Base> void accept(T param) {}

This method can be called with base1 without compiler error.

  • A `Consumer extends Base>` would accept a *specific* subclass of `Base` - not *any* subclass - but the compiler doesn't know which specific subclass, so it will only allow you to pass `null` as the parameter. – Andy Turner Apr 22 '20 at 23:08
  • Sure it does. consumer.accept(base1) refers to an object instance that is of class Base. It is in the code, the compiler does have it. – Joseph Janos Apr 23 '20 at 03:52
  • I did some further digging. If I replace 'extends' with 'super' it works. I even can invoke it with a subclass of Base. Obliviously this is the intent. – Joseph Janos Apr 23 '20 at 04:24
  • `Consumer extends Base> consumer = (SubclassOfBase t) -> /* something specific to SubclassOfBase */;` would also be a legal assignment. But then `consumer.accept(new Base())` has to be forbidden, because the consumer needs a `SubclassOfBase` but gets a `Base`. The reason is works with `Consumer super Base>` is that type means "a consumer to which it is safe to pass a `Base`: it's a *consumer of `Base`s*. This is explained in the dupe. – Andy Turner Apr 23 '20 at 08:04

0 Answers0