Consider the following scenario:
/**
* A sample interface.
*/
public interface MyInterface
{
}
/**
* First sample implementation of the above interface.
*/
public class MyClass1 implements MyInterface
{
public String toString()
{
return "[ My Class 1 ]";
}
}
/**
* Second sample implementation of the above interface.
*/
public class MyClass2 implements MyInterface
{
public String toString()
{
return "[ My Class 2 ]";
}
}
import java.util.Collection;
/**
* A service interface that declares a generic method
* returning a collection of subtype the interface defined above.
*/
public interface MyService
{
public <T> extends MyInterface<Collection<T>> myMethod();
}
import java.util.Arrays;
import java.util.Collection;
/**
* The implementation of the service interface
* that returns the generic type.
*/
public class MyServiceImpl implements MyService
{
@Override
public Collection<MyInterface> myMethod()
{
return Arrays.asList(new MyClass1(), new MyClass2());
}
}
import java.util.Collection;
/**
* Simple main class to drive the point
* I would like raise in the query below.
*/
public class MyMain
{
public static void main(String[] args)
{
MyService service = new MyServiceImpl();
Collection<MyClass1> list = service.myMethod();
// This works at runtime.
System.out.println(list);
for (MyClass1 obj : list)
{
// This throws ClassCastException at runtime.
System.out.println(obj);
}
}
}
In the above code, how can Java generics implementation allow the MyServiceImpl’s implementation to return a generic class when the MyService declaration talks about a specific subtype of a given type?
If I add the correct generic types
I get
I don’t see how you can get your example to compile without warning and trigger a ClassCastException.