Specification update: diamond and explicit generic constructor argument no longer supported
"Zdeněk Troníček"
tronicek at fit.cvut.cz
Tue May 17 23:04:57 PDT 2011
Ok, it makes sense to allow type parameter when calling a non-generified
method as "a concession to compatibility". But it does not make sense to
allow the same for constructors.
The argument "to be consistent" is false because it is illogical exception
from the language rules and each such exception should be justified by
strong motivation. You should not regard it as a new language rule because
the only motivation here is compatibility.
Z.
--
Zdenek Tronicek
FIT CTU in Prague
Dan Smith napsal(a):
> This is a rule, called out in specifically in the JLS with some extended
> discussion, that javac was failing to conform to. The change was to
> conform to the spec.
>
>>From JLS 3, 15.12.2.1:
>
>> The clause above implies that a non-generic method may be potentially
>> applicable to an invocation that supplies explicit type parameters.
>> Indeed, it may turn out to be applicable. In such a case, the type
>> parameters will simply be ignored.
>> This rule stems from issues of compatibility and principles of
>> substitutability. Since interfaces or superclasses may be generified
>> independently of their subtypes, we may override a generic method with a
>> non-generic one. However, the overriding (non-generic) method must be
>> applicable to calls to the generic method, including calls that
>> explicitly pass type parameters. Otherwise the subtype would not be
>> substitutable for its generified supertype.
>
> I'm not sure I believe that "the overriding (non-generic) method must be
> applicable to calls to the generic method"—I'm pretty sure this invariant
> is already violated in a number of ways elsewhere—but that was the
> rationale for the decision that was made when this was designed.
>
> Resolution for constructors works "using the same rules as for method
> invocations" (15.9.3). While clearly one could argue that the
> substitutability concerns above don't apply to constructors (nor to static
> or private methods...), the approach taken by the JLS was to consistently
> allow type arguments where none are needed.
>
> —Dan
>
>
> On May 17, 2011, at 3:50 PM, Joshua Bloch wrote:
>
>> Maurizio,
>>
>> Whoa, are you telling us that you folks intentionally made this legal?
>>
>> * Object o = new<String>Object();*
>>
>> This code makes no sense! Why should it be legal to pass a type
>> parameter
>> to a method or constructor that doesn't take one? I dearly hope that I
>> am
>> missing something.
>>
>> What am I missing?
>>
>> Josh
>>
>> On Tue, May 17, 2011 at 9:35 AM, Maurizio Cimadamore <
>> maurizio.cimadamore at oracle.com> wrote:
>>
>>> On 17/05/11 17:16, Anna Kozlova wrote:
>>>> 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.
>>> This is a deliberate change in javac in order to bring the compiler in
>>> sync with the spec [1]
>>>> 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?
>>>>
>>> The combination of explicit constructor type-arguments and diamond
>>> operator has been banned - the above code is not valid [2]
>>>
>>> Thanks
>>> Maurizio
>>>
>>> [1] - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5081782
>>> [2] -
>>>
>>> http://blogs.oracle.com/darcy/entry/project_coin_diamond_generic_constructors
>>>
>>>> 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