简体   繁体   English

从Java中的抽象项目类访问通用容器

[英]Accessing generic container from abstract item-class in java

I'm trying to implement a container which is generic about it's items. 我正在尝试实现一个通用的容器。 All possible item classes share a single abstract base class which provides access to the surrounding container. 所有可能的项目类共享一个单一的抽象基类,该抽象基类提供对周围容器的访问。

The following code shows my simplest approach: 以下代码显示了我最简单的方法:

public class GenericContainerProblem {

    public static void main(String[] args) {
        Container<SpecificItem> container = new Container<>();
        new SpecificItem(container);
    }

    private static class Container<ItemType extends AbstractItem> {
        private final List<ItemType> list = new ArrayList<>();

        public Container() {
            //
        }

        protected void addItem(ItemType specificItem) {
            list.add(specificItem);
        }
    }

    private static abstract class AbstractItem {
        protected final Container<? extends AbstractItem> container;

        public AbstractItem(Container<? extends AbstractItem> container) {
            this.container = container;
            container.addItem(this); // fails *
        }
    }

    private static class SpecificItem extends AbstractItem {
        public SpecificItem(Container<SpecificItem> container) {
            super(container);
            container.addItem(this); // succeeds
        }
    }

}

*) Error: The method addItem(capture#3-of ? extends GenericContainer.AbstractItem) in the type GenericContainer.Container<capture#3-of ? extends GenericContainer.AbstractItem> is not applicable for the arguments (GenericContainer.AbstractItem) *)错误: The method addItem(capture#3-of ? extends GenericContainer.AbstractItem) in the type GenericContainer.Container<capture#3-of ? extends GenericContainer.AbstractItem> is not applicable for the arguments (GenericContainer.AbstractItem) The method addItem(capture#3-of ? extends GenericContainer.AbstractItem) in the type GenericContainer.Container<capture#3-of ? extends GenericContainer.AbstractItem> is not applicable for the arguments (GenericContainer.AbstractItem)

This doesn't work as is because of the possible type mismatch allowed by the declaration ? extends AbstractItem 由于声明允许的类型不匹配,因此无法正常工作? extends AbstractItem ? extends AbstractItem . ? extends AbstractItem I think I need some type constraints telling the compiler the Container<?> -type used within AbstractItem is valid for this . 我想我需要某种类型的约束告诉编译器的Container<?>内使用型AbstractItem有效期为this

How can I declare/call the AbstractItem -class (and its constructor) in a way that it can access the container which is generic about a specific sub-class? 如何以可以访问有关特定子类通用的容器的方式声明/调用AbstractItem -class(及其构造函数)?

As far as I know, you need to make AbstractItem generic, in order to specify the type of the container it uses. 据我所知,您需要使AbstractItem为泛型,以便指定其使用的容器的类型。 You'd also need to use an unchecked cast in the AbstractItem constructor. 您还需要在AbstractItem构造函数中使用未经检查的强制转换。

But are you really sure you want such a bidirectional association between the container and the containee? 但是,您真的确定要在容器和容器之间建立双向关联吗? Perhaps you should rethink this design. 也许您应该重新考虑这种设计。

public class GenericContainerProblem {

    public static void main(String[] args) {
        Container<SpecificItem> container = new Container<>();
        new SpecificItem(container);
    }

    private static class Container<ItemType extends AbstractItem<ItemType>> {
        private final List<ItemType> list = new ArrayList<>();

        public Container() {
            //
        }

        protected void addItem(ItemType specificItem) {
            list.add(specificItem);
        }
    }

    private static abstract class AbstractItem<T extends AbstractItem<T>> {
        protected final Container<T> container;

        public AbstractItem(Container<T> container) {
            this.container = container;
            container.addItem((T) this);
        }
    }

    private static class SpecificItem extends AbstractItem<SpecificItem> {
        public SpecificItem(Container<SpecificItem> container) {
            super(container);
            container.addItem(this);
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM