Trouble with wildcards

Dan Smith daniel.smith at oracle.com
Tue Dec 17 10:21:39 PST 2013


On Dec 16, 2013, at 7:42 AM, Paul Sandoz <paul.sandoz at oracle.com> wrote:

> Hi Remi,
> 
> Reducing it down a little:
> 
> import java.util.*;
> import java.util.function.*;
> 
> class A {
> 
>  static class X {};
>  static class Y extends X {};
> 
>  public static void main(String[] args) {
>    Predicate<X> px = x -> x instanceof X;
>    Predicate<Y> py = y -> y instanceof Y;
> 
>    Predicate<? super Y> psy = px;
> 
>    Predicate<? super Y> superyandy = psy.and(py);    // <-- error
>    superyandy.test(new Y());
>  }
> }
> 
> $ javac -Xdiags:verbose A.java
> A.java:15: error: method and in interface Predicate<T> cannot be applied to given types;
>  Predicate<? super Y> superyandy = psy.and(py);    // <-- error
>                                       ^
>  required: Predicate<? super CAP#1>
>  found: Predicate<Y>
>  reason: argument mismatch; Predicate<Y> cannot be converted to Predicate<? super CAP#1>
>  where T is a type-variable:
>    T extends Object declared in interface Predicate
>  where CAP#1 is a fresh type-variable:
>    CAP#1 extends Object super: Y from capture of ? super Y
> 1 error
> 
> 
> It's confusing...

The concrete explanation: the 'and' method of the type Predicate<[something]>, where [something] is some type that is a supertype of Y (written CAP#1 in the error message), requires a Predicate<? super [something]>.  Is a Predicate<Y> a Predicate<? super [something]>?  No.  For example, consider the case in which [something] is Object.

The abstract explanation: we accept that 'px.and(py)' is a type error, right?  So it certainly doesn't make any sense that _up-casting_ px to one of its supertypes (Predicate<? super Y> in this case) would provide some functionality that px itself doesn't have.

—Dan


More information about the lambda-dev mailing list