Overload issue - more-specific-ness

Anna Kozlova anna.kozlova at jetbrains.com
Fri Mar 14 19:22:01 UTC 2014


>From spec 15.12.2.5 Choosing the Most Specific Method:

		In addition, a functional interface type S is more specific
than a functional interface type T for an expression exp if T is not a
subtype of S
			....
		R2 is void => true

Here SAM types are not subtypes from one another and one return type is void
(another is not) => most specific method could be chosen. Should spec
probably use |T| and |S| then?

Thanks,
Anna

-----Original Message-----
From: lambda-dev [mailto:lambda-dev-bounces at openjdk.java.net] On Behalf Of
Brian Goetz
Sent: Friday, March 14, 2014 6:48 PM
To: Peter Levart; Zhong Yu; lambda-dev at openjdk.java.net
Subject: Re: Overload issue - more-specific-ness

Yes, this is correct behavior.  The rule is that overloading methods whose
arguments are same-arity SAMs (and where other arguments can't be used to
disambiguate) are going to lead to ambiguities.

Bad: overloaded methods with functional interfaces of the same arity in the
same position

<T,U> void foo(Function<T,U>)
<T> void foo(ToIntFunction<T>)

Unless another non-functional argument can provide disambiguation

<T,U> void foo(String, Function<T,U>)
<T> void foo(int, ToIntFunction<T>)

OK: overload with the same functional interface in the same position <T,U>
void foo(Function<T,U>, String) <T,U> void foo(Function<T,U>, int)





On 3/14/2014 4:10 AM, Peter Levart wrote:
>
> On 03/14/2014 12:48 AM, Zhong Yu wrote:
>> Consider this program:
>>
>>      // like Runnable, but throws
>>      interface RunnableX extends Callable<Void>
>>      {
>>          void run() throws Exception;
>>
>>          default Void call() throws Exception
>>          {
>>              run();
>>              return null;
>>          }
>>      }
>>
>>      static void foo(RunnableX r){}
>>      static void foo(Callable<List<?>> c){}
>>
>> The overload should be fine, because both functional interfaces are 
>> 0-arg. And foo#2 should be more specific than foo#1.
>>
>> However the following program fails to compile
>>
>>      public void test()
>>      {
>>          foo( ()->new ArrayList<Void>() );
>>          // javac: reference to foo is ambiguous
>>          // both method foo(RunnableX) and method
>> foo(Callable<List<?>>) match
>>      }
>>
>> Is it the correct behavior or a bug? It seems to me that foo#2 should 
>> be the most-specific method here.
>>
>> ( If RunnableX does NOT extend Callable<Void>, the program compiles.)
>
> ...and selects foo(Callable). So when interfaces are not related the 
> structural type of Callable is prefered to that of RunnableX. If 
> RunnableX is related to (a subtype of) Callable then most specific 
> rule should prevail. I think. But it seems that structural fitness and 
> subtype specificness have equal weight here, so compiler is undecided.
>
> Regards, Peter
>
>>
>> Thanks,
>> Zhong Yu
>>
>
>


!DSPAM:35,5323412a213961640333909!




More information about the lambda-dev mailing list