Не может ли TreeSet проверить объекты компаратора во время компиляции? - PullRequest
0 голосов
/ 04 мая 2019

При создании экземпляра класса TreeSet в Java с конструктором по умолчанию (без аргументов) и добавлении двух объектов классов, которые не реализуют интерфейс Comparator, объект вызовет исключение времени выполнения. Может ли эта проверка быть реализована во время компиляции?

Я пробовал следующий код:

Dummy.java

public class Dummy {
}

TreeSetTest.java

import java.util.TreeSet;

public class TreeSetTest {

    public static void main(String[] argv) {
        TreeSet<Dummy> treeSet = new TreeSet<>();
        treeSet.add(new Dummy());
        treeSet.add(new Dummy());
    }
}

Компилятор должен пожаловаться при создании TreeSet, так как он не реализует Comparable.

Ответы [ 3 ]

1 голос
/ 04 мая 2019

Если бы конструктор TreeSet() не был общедоступным, вы могли бы проверить это во время компиляции с помощью заводского метода, например, так:

public static <E extends Comparable<? super E>> TreeSet<E> create() {
  return new TreeSet<>();
}

Вы можете вызвать это только с параметром типа, который естественным образомсравнимо:

TreeSet<String> a = TreeSet.create(); // ok
TreeSet<Object> b = TreeSet.create(); // error

Но конструктор публичный;и в Java нет языкового механизма, который позволял бы вам ограничивать параметры типа, используемые для вызова конструктора.

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

0 голосов
/ 04 мая 2019

Нет, компилятор не должен на это жаловаться.

Предположим, что у вас также есть подкласс Dummy, реализующий Comparable:

public class NotSoDummy extends Dummy implements Comparable {
    @Override
    public int compareTo(Object o) {
        ...
    }
}

Экземпляры этого класса должны быть добавлены в TreeSet без проблем. Компилятор не может проверить весь код (фактический, будущий), чтобы проверить, есть ли расширение Dummy, которое в конечном итоге может быть добавлено к TreeSet.

0 голосов
/ 04 мая 2019

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

static <E extends Comparable> boolean addWithCheck(TreeSet<E> treeSet, E e) {
    return treeSet.add(e);
}

А затем назовите это так:

TreeSet<Dummy> treeSet = new TreeSet<>();
addWithCheck(treeSet, new Dummy());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...