Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java泛型与泛型类的继承_Java_Generics_Java 7 - Fatal编程技术网

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

泛型容器似乎不能使用比泛型容器的函数签名更具体的类

如何使容器使用传递给它的函数之一的更特定类?可能吗?我是否误解了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 ?
        }
    }
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
不适用于泛型)