Почему я не могу присвоить этой универсальной переменной?

Я пытаюсь реализовать дерево, так что узлы являются общими:

public class BinarySearchTree<U extends BinarySearchTree.Node, T extends Comparable<? super T>> 
{
    public U root;
    ...

    public class Node {
        T data;
        U left;
        U right;

        public Node(T data) {
            this.data = data;
            left = null;
            right = null;
        }
    }
}

Но когда я пытаюсь выполнить назначение одним из моих методов, я получаю "Ожидаемый U, но обнаружен BinarySearchTree.Node:

public void display(U root) {
    if (root != null) {
        display(root.left); // gives compile time error
        System.out.print(" " + root.data);
        display(root.right); // gives compile time error
    }
}

2 ответа

Поскольку Node не статично, каждый Node экземпляр принадлежит содержанию BinarySearchTree пример. Но с помощью дженериков невозможно определить, к какому из них он принадлежит. Так что, если вы укажете BinarySearchTree.Node это может принадлежать любому BinarySearchTree, Поскольку вы также использовали необработанный тип (не игнорируйте предупреждения!), Неизвестно, что U является. Поэтому Java не может проверить, что root.left а также root.right одного типа, поэтому вы получаете ошибку.

Вы можете исправить ошибку компиляции, указав класс следующим образом:

class BinarySearchTree<U extends BinarySearchTree<U,T>.Node, T extends Comparable<? super T>> 
{ ... }

но это не устраняет основную проблему, заключающуюся в том, что узлы могут принадлежать любому BinarySearchTreeчто, вероятно, не то, что вы хотите.

Если вы действительно хотите использовать универсальный тип узла, вы можете сделать его статическим, чтобы он больше не принадлежал содержащим экземплярам:

public static class Node<U,T> 
{
    ...
}

Но я ставлю под сомнение необходимость иметь общий класс узлов в первую очередь. Обычно такие узлы считаются деталями реализации, и вы хотите иметь полный контроль над их созданием из своего класса. Это не может работать с общим узлом, потому что ваш класс не знает, какие узлы создавать.

Так что я бы определил ваш BinarySearchTree Класс следующим образом:

public class BinarySearchTree<T extends Comparable<? super T>>
{
    private Node<T> root;

    private static class Node<T> 
    {
        T data;
        Node<T> left;
        Node<T> right;
    }

    ...
}

Вы должны переписать определение класса в

public class BinarySearchTree<U extends BinarySearchTree<U, T>.Node, T extends Comparable<? super T>>
Другие вопросы по тегам