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