Diamond and Generic Methods
Dan Smith
daniel.smith at oracle.com
Thu May 5 12:04:00 PDT 2011
Paul,
I'm not quite sure what your concern is. But, whatever it is, it is orthogonal to diamond. As Maurizio's example demonstrates, any instance creation expression using diamond ('new Foo<>') can be re-expressed as an invocation of a generic method ('makeFoo()'). Inference in both cases behaves the same.
Taking a stab at it, I think you're saying inference chooses 'T' as the type argument for 'new ArrayList<>' (or has "the appearance" of choosing 'T'). This is incorrect. Inference chooses 'Object' as the type argument.
—Dan
On May 5, 2011, at 8:34 AM, Paul Benedict wrote:
> That's interesting. Because inference is supposed to be a help to
> explicit parametrization....
>
> This would be obviously rejected by the compiler:
> identity(new java.util.ArrayList<T>());
>
> Yet, as the compiler knows, the inference says T is Object so use Object.
>
> While totally understandable, I also think that will be a learning
> curve for some people. Java 5 taught lots of people that you can't
> instantiate using <T> but the new Java 7 code can give the appearance
> you suddenly can.
>
> Paul
>
> On Thu, May 5, 2011 at 10:18 AM, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com> wrote:
>> On 05/05/11 16:06, Jesper Öqvist wrote:
>>> So, after searching the archives and scouring the JSR334 v0.875 draft, I
>>> have a question about Diamond. While the specification draft does not
>>> explicitly disallow it, it seems weird that this works (Java7 developer
>>> preview b139):
>>>
>>> class C {
>>> <T> void identity(T a) { return a; }
>>> void m() {
>>> identity(new java.util.ArrayList<>());
>>> }
>>> }
>>>
>>> Since there is a distinction between raw types and parameterized types
>>> with inferred type arguments (in the discussion part of the Diamond
>>> section in JSR334), it would be interesting to know what type is
>>> instantiated in the above example.
>> Hi
>> The above code is equivalent to the following:
>>
>> class C {
>> static<Z> ArrayList<Z> makeArrayList() { return new ArrayList<Z>(); }
>>
>> <T> void identity(T a) { return a; }
>> void m() {
>> identity(makeArrayList());
>> }
>> }
>>
>> In both cases, an ArrayList<Object> is created - note that, because of
>> the restrictions in Java method type-inference, the information on
>> formal argument type is not used to infer a better type. In this
>> particular case it might not seem a big problem, but in the following
>> case you get a compile-time error:
>>
>> class C {
>> static<Z> ArrayList<Z> makeArrayList() { return new ArrayList<Z>(); }
>>
>> <T> T identity(T a) { return a; }
>> void m() {
>> //error - ArrayList<Object> found - expected ArrayList<String>
>> ArrayList<String> s = identity(makeArrayList());
>> }
>> }
>>
>>
>> Maurizio
>>
>>> /Jesper
>>>
>>
>>
>>
>
More information about the coin-dev
mailing list