It seem that a generic container cannot use a more specific class that the one of a function signature with generic container.
How can I have a container which use more specific class that the one of the function it is passed to? Is that possible ? Did I misunderstood generic in Java ?
Please, look at the code, as it may be easier to understand that the question.
package com.demo;
public class Entity {
public String baseField;
}
public class ChildEntity extends Entity {
public String extraField;
}
public class EntityContainer<T extends Entity> {
public T instance;
}
public class EntityContainerWithMeta<T extends Entity> extends EntityContainer<T> {
public String childContainerMetaData;
}
public class EntityConsumer<T extends Entity> {
public void consum(EntityContainer<T> container){
}
}
public class DemoGeneric {
private class ChildChildEntity extends ChildEntity{
public String extraExtraField;
}
// Objective :
// - using generic
// - with a data container that hold a more specific Klass ( Klass extends Entity)
// - pass it to a less specific consumer ( that consum Entity not Klass)
// real word use case:
// Entity is the base class for all my Business Specific Object
// Container are List<T extends Entity>
// Consumer are ListAdapter for ListView (extends BaseAdapter) (from Android framework)
public void demo() {
// compile: (but then container cannot return ChildEntity with its getter)
//EntityContainerWithMeta<Entity> demoContainer =
//new EntityContainerWithMeta<Entity>();
// don't compile:
EntityContainerWithMeta<ChildEntity> demoContainer = new EntityContainerWithMeta<ChildEntity>();
demoContainer.instance = new DemoGeneric.ChildChildEntity();
EntityConsumer<Entity> consumer = new EntityConsumer<Entity>();
// here is the problem:
// required: EntityContainer<Entity>
// found: EntityContainerWithMeta<ChildEntity>
consumer.consum(demoContainer);
// if
// ChildEntity extends Entity
// and
// EntityContainerWithMeta extends EntityContainer
// why is this not compiling ?
}
}
EDIT:
Thanks to the answers, I found this article: http://blog.informatech.cr/2013/03/15/covariance-and-contravariance-in-java/
That explain well the problem mentioned by @kocko and @MarkoTopolnik