Trouble with wildcards

Remi Forax forax at univ-mlv.fr
Tue Dec 17 14:50:32 PST 2013


On 12/17/2013 09:35 PM, Zhong Yu wrote:
> The static method works because it has an extra type parameter, which
> gives javac the freedom to make things work. The instance and() method
> has no such freedom (unless we give it a type parameter <S extends T>)
>
> Zhong Yu

The instance method and() is called on a Predicate<? super T>, and Predicate
is declared as class Predicate<T>, here T is already your extra type 
variable.

Rémi

>
> On Tue, Dec 17, 2013 at 1:46 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>> 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