Java Generic和遗传类的继承

时间:2015-01-28 12:15:56

标签: java generics java-7

似乎通用容器不能使用更具体的类,即具有通用容器的函数签名。

我怎样才能让一个容器使用更具体的类来传递给它的函数?这可能吗?我是否误解了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提到的问题

2 个答案:

答案 0 :(得分:1)

将您的consumer声明更改为:

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

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

因为generics are not implicitly polimorphic

答案 1 :(得分:0)

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

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

    }
}