Java 8 Type Inference - How reduction is done for generic constructors?
Asked Answered
K

1

6

I was reading the java 8 language specification type inference. It says that

List<String> ls = new ArrayList<>()

would be first reduced

ArrayList<α> -> List<String>

and then to

α <= String

and at the end to

α = String

I'm having a hard time understanding how the reduction of the constraint

ArrayList<α> -> List<String> to α <= String

was derived. It would be a great help if anyone can point out the logic using the java 8 language spec.

Here's the link to the reduction


Thanks #Holger for the explanation. Following is my take on the derivation of

new ArrayList<> -> List<String> to ArrayList<α> -> List<String>

Please correct me if I'm wrong.

First to find the temporary method for the constructor we use #15.9.3

  • Otherwise, the arguments to the constructor are the arguments in the argument list of the class instance creation expression, if any, in the order they appear in the expression.

  • If the class instance creation expression uses <> to elide class type arguments, a list of methods m1...mn is defined for the purpose of overload resolution and type argument inference.

Then #18.5.2 is used to derive

ArrayList<α> -> List<String>

Because of being a poly expression and not having any wild card type parameters;

  • Otherwise, the constraint formula ‹R θ → T› is reduced and incorporated with B2.
Kellerman answered 15/4, 2016 at 4:18 Comment(0)
L
4

I’m glad you didn’t ask how to come from new ArrayList<>() → List<String> to ArrayList<α> → List<String> as, while looking obvious, per applying §18.2.1, we will find it requires a discussion of the entire §15.9.3, followed by a discussion of §18.5.2.

Proceeding from ArrayList<α> → List<String> is easier:

§18.2.2. Type Compatibility Constraints

A constraint formula of the form ‹S → T› is reduced as follows:

  • … (five inapplicable bullets omitted)

  • Otherwise, the constraint reduces to ‹S <: T›.

 

§18.2.3. Subtyping Constraints

A constraint formula of the form ‹S <: T› is reduced as follows:

  • … (five irrelevant bullets omitted)

  • Otherwise, the constraint is reduced according to the form of T:

    • If T is a parameterized class or interface type, or an inner class type of a parameterized class or interface type (directly or indirectly), let A1, ..., An be the type arguments of T. Among the supertypes of S, a corresponding class or interface type is identified, with type arguments B1, ..., Bn. If no such type exists, the constraint reduces to false. Otherwise, the constraint reduces to the following new constraints: for all i (1 ≤ i ≤ n), ‹Bi <= Ai›..

So ArrayList<α> → List<String> is first reduced to ArrayList<α> <: List<String>, then, since List<String> is a parametrized interface, a corresponding super type of ArrayList<α> is identified, which will be List<α>, then, the constraint is reduced to a set of constraints for each corresponding type parameter (here we have exactly one), so we get α <= String.

Link answered 15/4, 2016 at 13:17 Comment(1)
Many thanks for the clarification. I updated the question with how I think the new ArrayList<>() -> List<String> was reduced to ArrayList<alpha> -> List<String>. It would be a great help if you could check that for any misconceptions.Kellerman

© 2022 - 2024 — McMap. All rights reserved.