Java Generic and inheritage of Generic 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提到的问题

consumer声明更改为:

EntityConsumer<? extends Entity> consumer = new EntityConsumer<ChildEntity>();

如果ChildEntity extends EntityEntityContainerWithMeta extends EntityContainer为什么不编译?

因为泛型不是隐式多态的。

看看以下内容是否有效,尽管我认为应该:

public class EntityConsumer {
    public <T extends Entity, M extends EntityContainer<T>> void consum(M container){
    }
}

最新更新