United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6840638 Project Coin: Improved Type Inference for Generic Instance Creation (aka 'diamond')
JDK-6840638 : Project Coin: Improved Type Inference for Generic Instance Creation (aka 'diamond')

Details
Type:
Enhancement
Submit Date:
2009-05-13
Status:
Closed
Updated Date:
2012-01-13
Project Name:
JDK
Resolved Date:
2012-01-13
Component:
tools
OS:
generic,windows_xp
Sub-Component:
javac
CPU:
x86,unknown,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
5.0,7
Fixed Versions:

Related Reports
Duplicate:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
One of the language changes in Project Coin is allowing inference on constructor call through the <> notation (aka 'diamond'); this bug tracks that work.

SUMMARY OF THE PROPOSAL

This proposal addresses the addition of limited type inference for
class instance creation expressions to the Java programming language.
In cases where parametrized types need to be explicitly declared for a
constructor, and the full parametrized type < T1 , T2 , ...Tn > of
that constructor is obvious from the context, then the  parameterized
type of the constructor can be replaced with an empty set of type
parameters: <>. The <>  construct is legal to use when constructing an
ob ject and either assigning it to a variable, or when passing  it as
a parameter.

For example, consider the following assignment statement:

Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

This is rather lengthy, so it can be replaced with this:

Map<String, List<String>> anagrams = new HashMap<>();

                                    

Comments
SUGGESTED FIX

There are two ways for implementing this proposal

1) generating a synthetic static factory method on the fly and re-use current support for method type-inference.

2) Change attribution so that inference can be applied in new expressions involving a generic class type.

Surprisingly the latter approach seems to be less problematic and conservative. It consists of replacing the type to be created with a ForAll type whose type variables are the formal type variables declared by such type (the actual types are missing since we are exploiting the diamond).

Once the ForAll has been created we can then rely on existing javac support for inferring an expression type given an assignment context.

The main difference between the two approaches is that the former is slightly more powerful as it allows inference from actual constructor arguments (so that both 15.12.2.7 and 15.12.2.8 are applied).

e.g. given the Foo class shown in 'evaluation':

Foo<?> = new Foo<>(""); 

the inferred type will be Foo<String> if the implementation technique is (1), while it will be simply Foo<Object> if the implementation technique is (2).
                                     
2009-05-13
SUGGESTED FIX

A webrev of this fix (2nd approach) is available at the following URL:
http://hg.openjdk.java.net/jdk7/tl/langtools/rev/8109aa93b212
                                     
2009-08-27
SUGGESTED FIX

See the following URL for a detailed discussion about the two implementations:

http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002159.html
                                     
2009-09-23
EVALUATION

This feature will significantly reduce the code that the user should type for initializing generic classes.

Let's analyze what is the expected behavior of a prototype supporting this feature. Given the following (generic) class declaration:

class Foo<X> {
...
Foo(X x) {...}
...
}

the '<>' notation should allow to initialize a generic class without explicitly providing an instantiation for Foo's type parameters (X in this case). Instead, the type parameters are inferred from the surrounding assignment context (if available).

e.g.

Foo<String> foo = new Foo<>(); //inferred as Foo<String>

A possible Java-model for implementing '<>' is to translate the constructor call into a call to a static synthetic factory method that the compiler adds to Foo.

class Foo<X> {
...
Foo(X x) {...}
static <Z> Foo<Z> create$(Z z) {}
...
}

Foo<String> foo = new Foo<>(); --> Foo<String> = Foo.create$();

Note: the purpose of the above translation is to give an idea about the semantics of the diamond operator and not about the actual implementation. An actual implementation should take into account aspects as:

* Generic constructors that declare their own type variables
* accessibility modifiers
* var-args
* boxing/unboxing conversion
                                     
2009-05-13



Hardware and Software, Engineered to Work Together