SAM resolution

Neal Gafter neal at gafter.com
Tue Nov 23 15:59:12 PST 2010


Overload resolution takes place in three phases: the first does not consider
methods that require boxing to match, and if a unique result is found then
that is the result of overload resolution.  The second phase allows boxing
and unboxing.  It appears that the lambda conversion implemented today does
not distinguish between these two phases.

On Tue, Nov 23, 2010 at 11:01 AM, Brian Goetz <brian.goetz at oracle.com>wrote:

> If I have:
>
>   interface Mapper<T, U> { U map(T t); }
>   interface IntMapper<T> { int map(T t); }
>
> and
>
> class Stream<T> {
>   <U> Stream<U> map(Mapper<T, U> mapper);
>   IntStream map(IntMapper<T> mapper);
> }
>
> and client code
>
>   stream.map(#{ f -> f.someIntField });
>
> I get this error:
>
> reference to map is ambiguous, both method <U>map(Mapper<T,U>) in Stream
> and
> method map(IntMapper<T>) in Stream match
>         stream.map(#{ f -> f.a });
>               ^
>   where U,T are type-variables:
>     U extends Object declared in method <U>map(Mapper<T,U>)
>     T extends Object declared in interface Stream
>
> Now, there are clearly two SAM types that are applicable here, so I
> understand
> the warning.  But the warning seems "surprising" in a sense; in method
> resolution, we "prefer" the match that doesn't require boxing to the one
> that
> does.  So if we have overloaded
>   m(Integer x)
> and
>   m(int x)
>
> and call m(3), we don't get an ambiguity error.
>
> It is likely to be a common case where people will define "specialized"
> primitive versions of methods along with generic ones.
>
>
>
>
>
>


More information about the lambda-dev mailing list