tags:

views:

132

answers:

2

In Java, why does an untyped invocation of a constructor of parameterised type provoke a compiler warning? Why is it okay to do similar thing with a static method? For example:

class Test<T> {

    Test() {}

    static <T> Test<T> create() {
        return new Test<T>();
    }

    @SuppressWarnings("unused")
    public static void main(String[] args) {
        Test<String> warning = new Test();  // compiler warning - why?
        Test<String> okay = Test.create(); // no warning here - why?
        Test<String> okay2 = Test.<String>create(); // why doesn't it need this?
    }

}
+8  A: 

Because you assign an untyped instance to a typed variable. Your three cases:

  1. Because new Test<String>() would be correct.
  2. Because Java supports automatic type inference based on the return type, i.e. it can imply the missign generic argument here, and inside the method, you've made the generic type explict, by using new Test<T>() (instead of just new Test()).
  3. Because of 2. ;-)
Konrad Rudolph
I have a question related to this:As to point 1), is that because Task() is equivalent to Task<Object>(), which would imply the risk of unsafe downcasts (you could e.g. add a Number to the Task)?
Matthias
@Matthias: no, not entirely – but for all practical intents and purposes (except the generated warnings), it is. `Task<Object>` is still explicitly typed, while the above isn’t. At runtime, it all resolves to `Object` anyway because of type erasure.
Konrad Rudolph
+1  A: 

Java does type inference on methods (which is why line 2 works and line 3 is not necessary), but not on constructors (which is why line 1 gives a warning).

It would be nice if Java did type inference on constructors too, but as of Java 6 it does not.

Kolibri