似乎通用容器不能使用更具体的类,即具有通用容器的函数签名。
我怎样才能让一个容器使用更具体的类来传递给它的函数?这可能吗?我是否误解了Java中的泛型?
请查看代码,因为可能更容易理解这个问题。
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 ?
}
}
编辑:
感谢答案,我发现这篇文章: http://blog.informatech.cr/2013/03/15/covariance-and-contravariance-in-java/
这很好地解释了@kocko和@MarkoTopolnik提到的问题
答案 0 :(得分:1)
将您的consumer
声明更改为:
EntityConsumer<? extends Entity> consumer = new EntityConsumer<ChildEntity>();
如果
ChildEntity extends Entity
和EntityContainerWithMeta extends EntityContainer
为什么不编译?
答案 1 :(得分:0)
看看以下是否有效,尽管我认为应该:
public class EntityConsumer {
public <T extends Entity, M extends EntityContainer<T>> void consum(M container){
}
}