Java Generic 和 Generic 的继承 Class
Java Generic and inheritage of Generic Class
通用容器似乎无法使用更具体的 class 通用容器的函数签名。
我怎样才能拥有一个使用更具体 class 传递给函数的容器? 这可能吗?我是否误解了 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提到的问题
看看下面的方法是否可行,虽然我认为应该可行:
public class EntityConsumer {
public <T extends Entity, M extends EntityContainer<T>> void consum(M container){
}
}
将您的 consumer
声明更改为:
EntityConsumer<? extends Entity> consumer = new EntityConsumer<ChildEntity>();
If ChildEntity extends Entity
and EntityContainerWithMeta extends EntityContainer
why is this not compiling ?
因为generics are not implicitly polimorphic.
通用容器似乎无法使用更具体的 class 通用容器的函数签名。
我怎样才能拥有一个使用更具体 class 传递给函数的容器? 这可能吗?我是否误解了 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提到的问题
看看下面的方法是否可行,虽然我认为应该可行:
public class EntityConsumer {
public <T extends Entity, M extends EntityContainer<T>> void consum(M container){
}
}
将您的 consumer
声明更改为:
EntityConsumer<? extends Entity> consumer = new EntityConsumer<ChildEntity>();
If
ChildEntity extends Entity
andEntityContainerWithMeta extends EntityContainer
why is this not compiling ?
因为generics are not implicitly polimorphic.