Overload resolution regression

Henry Jen henry.jen at oracle.com
Tue Nov 19 10:01:45 PST 2013



On 11/19/2013 08:43 AM, Jonathan Ross wrote:
> Or a pickMe(String) for that matter?
>

You will get a compiler error on reference is ambiguous. This is why we 
end up with Comparator.comparingXXX APIs.

Cheers,
Henry

> Thanks for the explanation, Remi.  Indeed, we were just using the
> coincidence of the Object fallback; it seems to predominantly affect our
> test fixtures - I hope, at least.  The nasty thing about it is that it
> leads to a runtime exception rather than a compilation error, so we may not
> find out for certain for a while.
>
>
> On Tue, Nov 19, 2013 at 9:02 AM, Paul Benedict <pbenedict at apache.org> wrote:
>
>> Ah, okay, that makes sense now. Filling me in on the background was a big
>> helper.
>>
>> For the sake of clarity, what would happen to Jonathan's example if there
>> was also a third pickMe(BigDecimal)?
>>
>>
>> On Tue, Nov 19, 2013 at 8:39 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>>
>>> On 11/19/2013 02:53 PM, Paul Benedict wrote:
>>>
>>>> I don't see how you can call the compiler "smarter" in this example.
>>>>
>>>
>>> 'smarter' because this is not the only use case :)
>>> Here is an example that fails to compile with 7 but compiles with 8
>>> (comparingByValue is also a method that only uses type variables to
>>> specify the return type)
>>>    Map<String,String> map = ...
>>>    map.entrySet().stream().sorted(Map.Entry.comparingByValue());
>>>
>>> For pickMe(unsafe()) the inference fails in 7 and uses Object as a
>>> fallback,
>>> it appears that it's what the user want but that's just a coincidence.
>>>
>>>   It is choosing pickMe(BigInteger) without >: BigInteger type being
>>>> present.
>>>>
>>>
>>>
>>> Don't forget that pickMe(null) also choose pickMe(BigInteger),
>>> it's the way the algorithm that choose the most specific method works
>>> since the beginning.
>>> here, the constraint is that T is a subtype of Object, so both
>>> pickMe(Object) and pickMe(BigInteger) are applicable,
>>> then the most specific algorithm chooses that pickMe(BigInteger) is
>> better
>>> than pickMe(Object).
>>>
>>> cheers,
>>> Rémi
>>>
>>>
>>>>
>>>> On Tue, Nov 19, 2013 at 5:30 AM, Remi Forax <forax at univ-mlv.fr <mailto:
>>>> forax at univ-mlv.fr>> wrote:
>>>>
>>>>      On 11/19/2013 01:43 AM, Jonathan Ross wrote:
>>>>      > Hi,
>>>>
>>>>      Hi Johnathan,
>>>>
>>>>      >
>>>>      > I recently started porting a 150k-line project to jdk 8 to try
>>>>      my hand at
>>>>      > the recent changes in the collection libraries. (Hadn't done
>>>>      this since
>>>>      > last year, my apologies!)
>>>>      >
>>>>      > I have run in to a large number of compilation errors:
>>>>      regressions in type
>>>>      > inference and overload resolution. A lot of these are in unit
>>>>      tests using
>>>>      > mockito and fest and other similar monadic apis that rely heavily
>> on
>>>>      > overload resolution.
>>>>
>>>>      It's not a regression, it's an enhancement :)
>>>>
>>>>      >
>>>>      > The code snippet below is a distilled version of my typical
>>>>      compilation
>>>>      > error: our test code relying on the compiler choosing the Object
>>>>      overload
>>>>      > by default.
>>>>      >
>>>>      >
>>>>      > import java.math.BigInteger;
>>>>      >
>>>>      > public class OverloadingRegression {
>>>>      >
>>>>      >      static <T> T unsafeCast(Object anObject) {
>>>>      >          return (T) anObject;
>>>>      >      }
>>>>      >
>>>>      >      public void showOverloadResolutionIssue() {
>>>>      >          pickMe(unsafeCast(new String()));
>>>>      >      }
>>>>      >
>>>>      >      private void pickMe(BigInteger o) { /* ClassCastException in
>>>>      > 1.8.0-ea-b115 */ }
>>>>      >
>>>>      >      private void pickMe(Object o) { /* fine, picked in 1.6 &
>>>>      1.7 */ }
>>>>      > }
>>>>      >
>>>>      >
>>>>      > Obviously the unsafeCast is not going to win any beauty prizes,
>> but
>>>>      > sometimes you just have to do this sort of thing.  My main point
>>>>      is: it
>>>>      > used to work in java 7, it doesn't any more.
>>>>      >
>>>>      > Is this a known issue (or is it even expected behaviour)?
>>>>
>>>>      Yes, it's the expected behavior, when you try do inference inside a
>>>>      method call,
>>>>      here unsafeCast is inside pickMe, in that case with jdk6 & 7, the
>>>>      inference
>>>>      is not done and T is replaceb by its bound (Object), with jdk8, the
>>>>      compiler is smarter,
>>>>      and find the most specific method first, here pickMe(BigInteger)
>>>>      is more
>>>>      specific than pickMe(Object) and then infers T (T = BigInteger).
>>>>
>>>>      >
>>>>      > I'm using 1.8.0-ea-b115, but I verified that it fails with all
>>>>      1.8 jdks I
>>>>      > have my box.  When I pass in -source 1.7 it does work. And when
>>>>      I do an
>>>>      > explicit cast to Object (of course).
>>>>
>>>>      so this is the correct behavior for 8, the new stream API heavily
>>>>      relies
>>>>      on that,
>>>>      and yes, this new semantics is not compatible with 1.7 in the case
>> the
>>>>      inference was failing,
>>>>      this is a known compatibility issue.
>>>>
>>>>      >
>>>>      > -- Jonathan Ross
>>>>      >
>>>>
>>>>      cheers,
>>>>      Rémi
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Cheers,
>>>> Paul
>>>>
>>>
>>>
>>
>>
>> --
>> Cheers,
>> Paul
>>
>>
>> ________________________________
>>
>> The information in this e-mail is intended only for the person or entity
>> to which it is addressed.
>>
>> It may contain confidential and /or privileged material. If someone other
>> than the intended recipient should receive this e-mail, he / she shall not
>> be entitled to read, disseminate, disclose or duplicate it.
>>
>> If you receive this e-mail unintentionally, please inform us immediately
>> by "reply" and then delete it from your system. Although this information
>> has been compiled with great care, neither IMC Financial Markets & Asset
>> Management nor any of its related entities shall accept any responsibility
>> for any errors, omissions or other inaccuracies in this information or for
>> the consequences thereof, nor shall it be bound in any way by the contents
>> of this e-mail or its attachments. In the event of incomplete or incorrect
>> transmission, please return the e-mail to the sender and permanently delete
>> this message and any attachments.
>>
>> Messages and attachments are scanned for all known viruses. Always scan
>> attachments before opening them.
>>
>


More information about the lambda-dev mailing list