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