Java泛型与泛型类的继承
泛型容器似乎不能使用比泛型容器的函数签名更具体的类 如何使容器使用传递给它的函数之一的更特定类?可能吗?我是否误解了Java中的泛型 请看一下代码,因为它可能更容易理解这个问题Java泛型与泛型类的继承,java,generics,java-7,Java,Generics,Java 7,泛型容器似乎不能使用比泛型容器的函数签名更具体的类 如何使容器使用传递给它的函数之一的更特定类?可能吗?我是否误解了Java中的泛型 请看一下代码,因为它可能更容易理解这个问题 package com.demo; public class Entity { public String baseField; } public class ChildEntity extends Entity { public String extr
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 ?
}
}
package.com.demo;
公共类实体{
公共字符串基址;
}
公共类ChildEntity扩展实体{
公共字符串外域;
}
公共类实体容器{
公共行政实例;
}
公共类EntityContainerWithMeta扩展EntityContainer{
公共字符串childContainerMetaData;
}
公共类实体消费者{
公共void consum(EntityContainer容器){
}
}
公共类DemoGeneric{
私有类ChildEntity扩展了ChildEntity{
公共字符串外域;
}
//目标:
//-使用通用
//-使用包含更具体的Klass(Klass扩展实体)的数据容器
//-将其传递给不太特定的消费者(该消费者实体不是Klass)
//真实单词用例:
//实体是我所有业务特定对象的基类
//集装箱清单
//消费者是ListView的ListAdapter(扩展BaseAdapter)(来自Android框架)
公共空间演示(){
//compile:(但是容器不能返回带有getter的ChildEntity)
//带有Meta demoContainer的EntityContainer=
//新EntityContainerWithMeta();
//不要编译:
EntityContainerWithMeta demoContainer=新的EntityContainerWithMeta();
demoContainer.instance=新建DemoGeneric.ChildEntity();
EntityConsumer consumer=新的EntityConsumer();
//问题是:
//必需:EntityContainer
//已找到:EntityContainerWithMeta
消费者消费(demoContainer);
//如果
//子实体扩展实体
//及
//EntityContainerWithMeta扩展EntityContainer
//为什么这不是编译?
}
}
编辑:
多亏了这些答案,我找到了这篇文章:
这很好地解释了@kocko和@MarkoTopolnik提到的问题,看看下面的方法是否有效,尽管我认为应该:
public class EntityConsumer {
public <T extends Entity, M extends EntityContainer<T>> void consum(M container){
}
}
公共类EntityConsumer{
公共空隙消耗量(M集装箱){
}
}
将您的消费者声明更改为:
EntityConsumer<? extends Entity> consumer = new EntityConsumer<ChildEntity>();
EntityConsumer这不是Java泛型的怪癖,而是一个基本事实Container
根本不是Container
,就像Hotel
不是Hotel
@MarkoTopolnik使用数组容器一样,这让我觉得这是我的错误,或者是Java泛型的局限。例如:您可以将“ChildEntity[]childEntityContainer”设置为“Entity[]heterogeneousContainer”,这实际上是因为Java的数组类型系统已损坏,导致运行时类型检查失败。这也不会编译:EntityConsumer类中的方法consum无法应用于给定类型;consumer.consum(demoContainer);^必需:找到EntityContainer:EntityContainerWithMeta原因:无法通过方法调用转换将实际参数EntityContainerWithMeta转换为EntityContainer,其中T是类型变量:T扩展类EntityConsumer中声明的实体,其中CAP#1是新类型变量:CAP#1从捕获扩展实体?扩展实体请注意,如果它进行编译,我将失去我的目标,即让消费者接受任何实体子类。第一个解决方案编译!!谢谢你的检查,我不确定第二个。第一个是你需要的吗?我想这是你能得到的最接近的,但是我“丢失”了新的EntityConsumer****()
,但是EntityConsumer
将适用于Entity的所有子类,或者至少你可以作为Entity
访问它们,但我不能“享受”在我的消费者中有一个简单的getter,它将返回良好的实体子类而不强制转换,我也不能使用实体子类的字段。(因为instanceof
不适用于泛型)