Java泛型自引用:它安全吗?

一个简单的接口:

public interface Node<E extends Node<E>>
{
    public E getParent();

    public List<E> getChildren();

    default List<E> listNodes()
    {
        List<E> result = new ArrayList<>();

        // ------> is this always safe? <-----
        @SuppressWarnings("unchecked")
        E root = (E) this;

        Queue<E> queue = new ArrayDeque<>();
        queue.add(root);

        while(!queue.isEmpty())
        {
            E node = queue.remove();

            result.add(node);

            queue.addAll(node.getChildren());
        }

        return result;
    }
}

我发现这始终是Node <E>的一个实例(根据定义)。 但我无法想象这不是E的一个实例...... 由于E扩展了Node <E>,Node <E>也不应该等同于E的定义吗?你能给出一个Node <E>实例的对象的例子,但它不是E的实例吗?

上面是一个简化的例子。 为了说明为什么我需要一个自我约束,我增加了一些复杂性:

public interface Node<E extends Node<E, R>, R extends NodeRelation<E>>
{
    public List<R> getParents();

    public List<R> getChildren();

    default List<E> listDescendants()
    {
        List<E> result = new ArrayList<>();

        @SuppressWarnings("unchecked")
        E root = (E) this;

        Queue<E> queue = new ArrayDeque<>();
        queue.add(root);

        while(!queue.isEmpty())
        {
            E node = queue.remove();

            result.add(node);

            node.getChildren()
                .stream()
                .map(NodeRelation::getChild)
                .forEach(queue::add);
        }

        return result;
    }
}

public interface NodeRelation<E>
{
    public E getParent();

    public E getChild();
}


 
java
generics
this
self-reference
1s

推荐解答

一个简单的例子来说明问题:不同类型节点的节点:

class NodeA implements Node<NodeA> {
    ...
}

class NodeB implements Node<NodeA> {
    ...
}

在这种情况下,E root =(E)这将解析为NodeA root =(NodeA)this,这是NodeB。 这是不相容的。

  nopapp推荐