Type inference: bug or feature?

Remi Forax forax at univ-mlv.fr
Mon Jul 27 10:54:57 UTC 2020


----- Mail original -----
> De: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> À: "Justin Dekeyser" <justin.dekeyser at gmail.com>, "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Envoyé: Lundi 27 Juillet 2020 12:26:40
> Objet: Re: Type inference: bug or feature?

> CC'ing compiler-dev
> 
> Hi Justin,
> the behavior you are observing is normal. For a Java expression to be
> able to be influenced by type inference it has to be a poly expression
> (where poly stands for _many_ as in, the same expression can have many
> types).
> 
> At the time we did Java 8 we briefly considered making cast expressions
> part of the poly expression dance (like lambdas, method references,
> method calls, parens, new creation expression, conditionals and switch
> expression - see JLS 15.2), but the rule which dictate cast conversion
> (JLS 5.5) are so complex (as they have to take into account possibility
> for unchecked cast, etc.) that it felt like touching them was a very
> risky move, with no clear benefit.

There was another reason :)

The idea behind introducing generics is to get ride of casts because they are a hazard at runtime.
So allowing people to use casts as poly expression goes in the wrong direction, add more casts.

Instead of using a cast, it's better to use explicit type arguments,
  TheClass.<TheTypeYouWantHere>emptyList()

[...]

> 
> Cheers
> Maurizio

regards,
Rémi

> 
> On 26/07/2020 18:22, Justin Dekeyser wrote:
>> Dear all,
>>
>> I'm not sure but I think I've found a bug in Java type inference mechanism.
>> It may also be a feature, so I'll expose the problem to you below; in terms
>> of Integer, Number and List, although you'll quickly realize it will work
>> wrong in any similar situation.
>>
>> Let's assume I have
>>
>> static <U, V extends U> List<U> emptyList(Class<U> magnet) {
>>     return Collections.emptyList();
>> }
>>
>> Then the following codes does not compile (for the same reason):
>>
>> var x = (List<Integer>) emptyList(Number.class);
>> List<Integer> x = (List<Integer>) emptyList(Number.class);
>>
>> incompatible types: List<Number> cannot be converted to List<Integer>
>>
>> however, the following do compile:
>>
>> var x = emptyList(Number.class); // inferred to List<Number>
>> List<Integer> x = emptyList(Number.class); // no mistake here, it's Integer
>> on the left
>>
>> Is this the expected behavior? Why does casting operation here interfere
>> with type inference like this?
>>
>> Regards,
>>
>> Justin Dekeyser
>>
>>
>>
>>
>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
>> Garanti
>> sans virus. www.avast.com
>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
> > <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>


More information about the core-libs-dev mailing list