alasdairg
alasdairg

Reputation: 2118

Java Generics - vanishing type information?

OK - I know that Java generics can be a minefield for the unwary, but I just came across a non-intuitive (to me anyway) behavior that I was wondering if anyone can explain: First of all, here's a class that compiles:

public class Dummy {

   public List<? extends Number> getList() {
      return new ArrayList<Number>();
   }

   public static void main(String[] args) {
      Dummy dummy = new Dummy();
      for (Number n: dummy.getList()) {
         System.out.println(n);
      }    
   }
}

Simple stuff. Now, I make a single change by adding a type parameter T to Dummy:

public class Dummy<T> {

Now the class fails to compile, giving the error "Type mismatch: cannot convert from element type Object to Number" on the for() statement

It appears that because I have parameterized the Dummy class, the creation of the new Dummy() in the main method (without specifying a type parameter), causes the type information for the getList() method to no longer be available: The compiler no longer knows the type of the list elements, so they can't be assigned to a loop variable of type Number. Why does this type information go missing, given that the <T> declaration on the class has nothing at all to do with the <? extends Number> declaration on the getList() method?

Furthermore, if I now change my instantiation of Dummy to be:

Dummy<?> dummy = new Dummy();

Then the type information becomes available again, and the class compiles once more. So why is a "Dummy of unknown type" allowed to retain its getList() type information whilst a Dummy (presumably of unknown type since I didn't specify a parameter) loses it?

Maybe I'm the Dummy :-)

Upvotes: 2

Views: 333

Answers (2)

denis.zhdanov
denis.zhdanov

Reputation: 3744

The general idea is that all type-related information is erased if you use raw version of parameterized type. That includes either type information implied by class type parameters or generic methods parameters as well.

Very similar example is described here.

Upvotes: 4

non sequitor
non sequitor

Reputation: 18806

I've come across this before but explaining it might cause you further confusion so I'm linking you to the JLS section on "Raw Types" which you can read to fully understand what's going on then you can come back with further questions if you don't get it.

Upvotes: 0

Related Questions