Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics and return types

Tags:

java

generics

I just ran into something that I do not understand. Why isn't the for each loop below legal when the second identically one is?

public interface SomeInterface<T> {
   List<SomeNamedObject> getObjects();
   void doSomething(P1 p1, T p2);
}

public class SomeNamedObject {
    private String text;
}

public class Clazz {

    private SomeInterface someInterface;

    ...

    public void someMethod() {
       // Error Type mismatch: cannot convert from element type Object to TestClass.SomeNamedObject
       for (SomeNamedObject someNamedObject :  someInterface.getObjects()) {
             // This loop won't compile as the someInterface.getObjects returns just a List and not a List<SomeNamedObject>
       }

       // Warning Type safety: The expression of type List needs unchecked 
       // conversion to conform to List<TestClass.SomeNamedObject>
       List<SomeNamedObject> objects = someInterface.getObjects();
       for (SomeNamedObject someNamedObject :  objects) {
             // This loop compiles 
       }
    }
}
like image 579
AnAmuser Avatar asked Dec 20 '11 18:12

AnAmuser


1 Answers

Because your instance variable private SomeInterface someInterface doesn't specify its generic type parameter then all use of generics is disabled for someInterface. This means that someInterface.getObjects() has the raw return type List rather than List<SomeNamedObject>. This is the reason the first example does not compile.

In the second example List<SomeNamedObject> objects = someInterface.getObjects() is putting in an explicit type for the list. You will see a warning when you do this though because the type safety is not guaranteed. This is the same behaviour you would see if getObjects() was defined as just List getObjects() without the type parameter.

like image 74
mikej Avatar answered Sep 22 '22 12:09

mikej