Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.
like image 367
psaw.mora Avatar asked Apr 15 '16 04:04

psaw.mora


People also ask

What is type inference and generic methods in Java?

Type Inference and Generic Methods. Generic Methods introduced you to type inference, which enables you to invoke a generic method as you would an ordinary method, without specifying a type between angle brackets.

How to replace type arguments in a generic class constructor?

You can replace the type arguments required to invoke the constructor of a generic class with an empty set of type parameters ( <>) as long as the compiler can infer the type arguments from the context. This pair of angle brackets is informally called the diamond.

How does the compiler infer the type of a generic class?

The compiler infers the type String for the formal type parameter, T, of the constructor of this generic class (because the actual parameter of this constructor is a String object). Compilers from releases prior to Java SE 7 are able to infer the actual type parameters of generic constructors, similar to generic methods.

What is type inference in Java 8?

Type inference is a feature of Java which provides ability to compiler to look at each method invocation and corresponding declaration to determine the type of arguments. Java provides improved version of type inference in Java 8. the following example explains, how we can use type inference in our code:


1 Answers

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.

like image 87
Holger Avatar answered Sep 16 '22 23:09

Holger