Trouble with wildcards
Remi Forax
forax at univ-mlv.fr
Tue Dec 17 11:46:41 PST 2013
On 12/17/2013 07:21 PM, Dan Smith wrote:
> 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.
I disagree, Predicate<Y> is a Predicate<? super [something]> because Y
can capture
? super [something], otherwise it means that 'and' should be a static
method and not an instance method.
The following code compiles:
static <T> Predicate<T> staticAnd(Predicate<? super T> that, Predicate<?
super T> other) {
...
}
Predicate<? super String> p1 = null;
Predicate<? super String> p2 = null;
Predicate<? super String> p3 = staticAnd(p1,p2);
but not
Predicate<? super String> p3 = p1.and(p2);
which is not very logical.
>
> 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
Rémi
More information about the lambda-dev
mailing list