Huston, we have a problem !

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Feb 18 07:07:49 PST 2011


On 18/02/11 14:45, Florian Weimer wrote:
> * Rémi Forax:
>
>> public class DiamondRaw {
>>     public static void main(String[] args) {
>>       String s = new String<>("foo");
>>     }
>> }
> After seeing this example, I've been wondering why the diamond is
> needed at all.  Wouldn't it be sufficient to suppress the raw type
> warning in all places where you could add a diamond, without
> introducing a compilation error?  What crucial piece of information
> does the presence of a diamond provide?
>

Here's an example where the two constructs (raw type and diamond) behave 
differently:

interface I {}
class Foo<X> {
     Foo(X x) {};
     Foo<X> get(X x) { return this; };
}

class Test {
    void test(I i) {
       Foo<?> f1 = new Foo(1).get(""); //ok - can pass String where 
Object is expected
       Foo<?> f2 = new Foo<>(1).get(""); //fail - cannot pass String 
where Integer is expected
    }
}

In short, a raw type doesn't have any info about type-parameter 
instantiation - anything that will work with the erasure of the generic 
class Foo, will also work with the raw type Foo. On the contrary, Foo<> 
is a full parameterized type - as such, javac is able to apply strict 
type-checking as it if were an ordinary parameterized type.

In terms of language evolution, it is also important not to replace and 
existing concept (raw type) with a new one (generic type with 
unspecified type-parameters, as in diamond). The problem becomes more 
evident as soon as you start exploring new language features that imply 
exact runtime information about generic types (i.e. reification). If we 
were to add reified generics to Java, it is very likely that we will 
have to support runtime raw types (!!) for backwards compatibility - so 
the syntactic distinction between diamond and raw turns out to be quite 
sweet.

Maurizio



More information about the coin-dev mailing list