Specification update: diamond and explicit generic constructor argument no longer supported

Anna Kozlova Anna.Kozlova at jetbrains.com
Tue May 17 09:16:43 PDT 2011


Hello,

may be here is not the best place to ask, but I am not sure whether the
following was an intentional change or a bug?

{code}
  Object o = new <String>Object();
{code}

Compiles in build 142 but didn't in jdk6 builds. 

The same question but this time with diamond operator: what if constructor
doesn't have type parameters but they are still passed?
{code}
  class Foo<T> {
      Foo(T t) {super();}
  }  
{code}

Usage:
{code}
  new <Integer> Foo<>("");
{code}
How compilation should fail?

Thank you
Anna Kozlova
JetBrains Inc.
http://www.jetbrains.com
"Develop with pleasure!" 


-----Original Message-----
From: coin-dev-bounces at openjdk.java.net
[mailto:coin-dev-bounces at openjdk.java.net] On Behalf Of joe.darcy at oracle.com
Sent: Saturday, May 07, 2011 12:50 AM
To: coin-dev at openjdk.java.net
Subject: Specification update: diamond and explicit generic constructor
argument no longer supported

Hello.

To address an issue in the specification, the JSR 334 expert group has 
decided to ban the combination of diamond together with explicit 
constructor type arguments. For background, a constructor can have two 
sets of type arguments. In a parameterized class, constructors can have 
type arguments corresponding to the class's type parameters. This is the 
common case and the type arguments appear to the right of the class name 
and "new" as in "new ArrayList<String>()". In addition, if a constructor 
declares its very own type parameters (which can be done whether or not 
the enclosing class is parameterized), then those type arguments appear 
between the "new" token and the class name as in "new <Integer> 
ConstructorWithTypeParameter(Integer.valueOf(42))".

As with generic methods, the type arguments of generic constructors are 
usually inferred and not explicitly passed. However, generic 
constructors are much less common than generic methods.

After the specification change, using diamond to infer the class type 
parameters but explicitly passing the constructor type parameters is 
forbidden. However, the other three combinations of explicitly passing 
type arguments versus inferring them are supported, as shown in the 
table below.

class Foo<T extends Number> {
      <S extends T> Foo(S s) {super();}
}

Class      C'tor        Supported   Example
Explicit   Explicit     Yes         new <Integer> Foo<Number>(null);
Explicit   Inferred     Yes        new Foo<>(null);
Inferred   Explicit     No         new <Integer> Foo<>(null); // compile 
error
Inferred   Inferred    Yes        new Foo<>(null);

The substitution that was used to formally describe the semantics of 
diamond did not fully propagate constraints if there was a typing 
relationship between the type parameters of the constructor and the type 
parameters of the class. Lifting the imposed restriction on the banned 
combination of explicit and inferred type arguments can be revisited in 
future work in the context of broader type inference getting added to 
the Java language.

Since generic constructors are so uncommon, adding this restriction 
about combining them with diamond should have little effect to most 
programs. For example, none of the uses of diamond in the JDK had to be 
updated as a result of this change. A changeset implementing this 
specification change has been pushed [1] and will appear in subsequent 
promoted builds of JDK 7.

-Joe

[1] http://hg.openjdk.java.net/jdk7/tl/langtools/rev/4caf17560ae0


!DSPAM:35,4dc47a19236162090119686!




More information about the coin-dev mailing list