tags:

views:

175

answers:

4

Most references I've seen, and my IDE's code completion all have my specifying a Generic type on both a variables type and its implementation eg.

List<String> string = new ArrayList<String>();

Recently I've started skipping the generic type on the implementation eg.

List<String> strings = new ArrayList();

assuming that the compiler is only checking against the type for it's spiffy generics voodoo, and that the implementation shouldn't care, as its generic types are erased when it's compiled and should not affect run-time at all.

Am I being naive? Is there a reason to include the generic type on the implementation?

+6  A: 

The compiler may allow you to write code with such assignments (depending on your warnings/errors settings) but it is unsafe. Here's an example:

List<Date> dates = new ArrayList<Date>();
List list = dates;
List<String> strings = list;

strings.add("a");
Date d = dates.get(0); // Boom!!
Itay
ah, that would be what this note refers to: Note: Test.java uses unchecked or unsafe operations.
Cogsy
Yes, that's the scenario behind the warning
Itay
+4  A: 

Is there a reason to include the generic type on the implementation?

It's required as it won't necessarily be the same:

List<? extends Number> numbers = new ArrayList<Integer>();

One way of avoiding it for common cases is to have static utility methods, and let the compiler's type inference do the rest:

class CollectionUtilities {
   static <T> ArrayList<T> arrayList () { return new ArrayList<T>(); }
}

...

import static CollectionUtilities.*;

List<Integer> numbers = arrayList();

This is type safe, and doesn't require the generic type on the implementation. (The reason itay's example is not safe the lack of the generic type on the type of the list variable, not anything to do whether you need to specify generic type on both the variable's type and the implementation.)

Pete Kirkham
A: 

Whilst it would be nice to be able to omit type generic definition in these cases, it does produce warnings. (There is a serious proposal to extend the language with a non-raw syntax for inferring type here.) You really should not get into the habbit of ignoring compiler warnings. As Pete Kirkham you can use the type inference that already exists (although I suggest using shorter names).

Tom Hawtin - tackline
A: 

In the simple case you show, your code is totally workable because (after type erasure) the compiler will generate the exact same byte code.

However, in only slightly more complicated case you can get into trouble. This is why the compiler wants to issue a warning for this type of code. In addition, if type reification is added (Java 8?) then this code will be broken. Unless Java 7 adds type inference first. :-)

Meanwhile it's probably best to write warning clean code.

Darron