3

我看到 EnumSet.of() 返回EnumSet类型的对象的实例。但我无法弄清楚哪个类实际实现了这个抽象类?如果没有子类化,如何获得抽象类型 EnumSet 的实例?

4

5 回答 5

6

这是java中的2个扩展类EnumSet

1. RegularEnumSet
2. JumboEnumSet

您可以使用 EnumSet 的静态方法(如 等)创建实例EnumSet#noneOfEnumSet#allOf实际上返回的实例RegularEnumSetJumboEnumSet取决于条件。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);
}
于 2018-04-24T17:15:43.353 回答
5

您不直接创建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();
...
于 2018-04-24T17:15:46.427 回答
0

要查找此信息,您可以查看所有代码,或打印出getClass()作为示例返回的对象的代码,但更简单的方法是使用您的 IDE。

导航到EnumSet并单击显示实现的图标

EnumSet 的实现

这将向您显示 EnumSet 的所有可用子类的列表。

于 2018-04-24T17:43:28.860 回答
0

用于枚举类型的专用 Set 实现。枚举集合中的所有元素都必须来自一个枚举类型,该枚举类型在创建集合时显式或隐式指定。

如果EnumSet! 但是你也不需要扩展它,因为它的目的是有一个工厂方法来从指定的元素创建一个 Set :

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);

您在这里找到了更多信息...

于 2018-04-24T17:21:40.423 回答
0

其他答案已经回答了EnumSet实际实现抽象类的具体子类是什么EnumSetEnumSet当我们没有子类化它时,我将尝试阐明如何获得抽象类型的实例。

请注意,EnumSet它没有构造函数,因此不打算像普通类一样使用它:

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

相反,为了创建一个EnumSet,我们使用它的一个静态初始化器(例如of)。这些初始化器将在内部创建一个类型的对象JumboEnumSet(如果枚举常量的数量很大)或RegularEnumSet(否则)并返回该对象的引用。

由于JumboEnumSetRegularEnumSet都是 的子类EnumSet,因此可以将它们分配给类型变量EnumSet(这称为扩展引用转换)。

这样做的美妙之处在于,当我们使用 type 的变量时EnumSet,我们不必知道我们使用的是哪个具体实现。实际上,两者JumboEnumSetRegularEnumSet都是包中的私有类,java.util因此我们甚至无法直接创建它。

您可以通过其源代码探索更多EnumSet内部实现方式(例如,请参阅此处了解 Java 9 的版本)。

另一个在 Java 中常用但实际上不是具体类的类型的例子是Stream. Stream实际上是一个接口。

于 2018-04-24T18:04:42.400 回答