Какой класс в Java реализует абстрактный класс EnumSet? - PullRequest
0 голосов
/ 24 апреля 2018

Я вижу, что EnumSet.of () возвращает экземпляр объекта типа EnumSet . Но я не могу понять, какой класс на самом деле реализует этот абстрактный класс? Как вы можете получить экземпляр абстрактного типа EnumSet, если вы не вложили его в подкласс?

Ответы [ 5 ]

0 голосов
/ 24 апреля 2018

Другие ответы уже ответили, каковы конкретные подклассы EnumSet, которые фактически реализуют абстрактный класс EnumSet. Я попытаюсь прояснить, как мы можем получить экземпляр абстрактного типа EnumSet, если мы не подклассифицировали его.

Обратите внимание, что EnumSet не имеет конструктора, поэтому он не предназначен для использования как обычный класс:

EnumSet set = new EnumSet(...); // not like this

Скорее, чтобы создать EnumSet, мы используем один из его статических инициализаторов (например, of). Эти инициализаторы внутренне создадут объект типа JumboEnumSet (если число констант enum велико) или RegularEnumSet (в противном случае) и вернут ссылку на этот объект.

Поскольку JumboEnumSet и RegularEnumSet оба являются подклассами EnumSet, их можно назначить переменной типа EnumSet (это известно как расширяющее эталонное преобразование ).

Прелесть этого в том, что когда мы используем переменную типа EnumSet, нам не нужно знать, какую конкретную реализацию мы используем. Фактически, оба JumboEnumSet и RegularEnumSet являются частным классом в пакете java.util, поэтому мы не можем даже создать его напрямую.

Вы можете узнать больше о том, как EnumSet реализовано внутри через его источник (см., Например, здесь для версии Java 9 ).

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

0 голосов
/ 24 апреля 2018

Чтобы найти эту информацию, вы можете просмотреть весь код или распечатать getClass() объекта, возвращенного в качестве образца, но более простым способом является использование вашей IDE.

Перейдите к EnumSet и щелкните значок, показывающий реализации

implementations of EnumSet

. Здесь показан список всех доступных подпрограмм.доступны классы EnumSet.

0 голосов
/ 24 апреля 2018

Вы не создаете напрямую экземпляры EnumSet.Это делается статическими фабричными методами, такими как:

enum Demo { YES, NO, FILENOTFOUND }

EnumSet<Demo> all = EnumSet.allOf(Demo.class);
EnumSet<Demo> notNo = EnumSet.of(Demo.YES, Demo.FILENOTFOUND);
EnumSet<Demo> none = EnumSet.noneOf(Demo.class);

Полученные наборы являются изменяемыми, то есть вы можете сделать:

EnumSet<Demo> set = EnumSet.noneOf(Demo.class);  // start with an empty set
...
set.add(Demo.YES);
set.remove(Demo.NO);
...
set.clear();
...
0 голосов
/ 24 апреля 2018

Специализированная реализация Set для использования с типами enum.Все элементы в наборе перечислений должны происходить из одного типа перечисления, который указывается, явно или неявно, при создании набора.

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

public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest)

Он создает объект для вас.Часто EnumSets используются для комбинирования эффектов, будь то текстовые стили, например, BOLD и UNDERLINE, или с цветами ...

enum Color { GREEN, RED, BLUE };
EnumSet <Color> yellow = EnumSet.of(Color.RED, Color.GREEN);

Вы нашли дополнительную информацию здесь ...

0 голосов
/ 24 апреля 2018

Вот 2 класса в Java, которые расширяются EnumSet

1. RegularEnumSet
2. JumboEnumSet

Вы можете создать экземпляр, используя статические методы EnumSet, такие как EnumSet#noneOf, EnumSet#allOf и т. Д., Которые на самом деле возвращают экземпляр RegularEnumSet или JumboEnumSet в зависимости от условия. EnumSet#of Внутренние вызовы EnumSet#noneOf. Пожалуйста, обратитесь к приведенному ниже коду из Java, чтобы увидеть, как EnumSet#noneOf работает

public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
    Enum<?>[] universe = getUniverse(elementType);
    if (universe == null)
        throw new ClassCastException(elementType + " not an enum");

    if (universe.length <= 64)
        return new RegularEnumSet<>(elementType, universe);
    else
        return new JumboEnumSet<>(elementType, universe);
}
...