【问题标题】:Which class in Java implements the abstract class EnumSet?Java中哪个类实现了抽象类EnumSet?
【发布时间】:2018-10-05 01:16:29
【问题描述】:

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

【问题讨论】:

  • 你为什么不看看EnumSet.of()的实现?
  • @azurefrog:不能实例化抽象类,但可以获取抽象类型的实例。例如 myAbstractClass abs= new myImplementation();这里 abs 是 myAbstractClass 类型的一个实例。
  • 试试System.out.println(EnumSet.noneOf(RetentionPolicy.class).getClass());

标签: java enumset


【解决方案1】:

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

注意EnumSet 没有构造函数,所以它不能像普通类一样使用:

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

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

由于JumboEnumSetRegularEnumSet 都是EnumSet 的子类,因此可以将它们分配给EnumSet 类型的变量(这称为widening reference conversion)。

这样做的好处在于,当我们使用EnumSet 类型的变量时,我们不必知道我们使用的是哪个具体实现。事实上,JumboEnumSetRegularEnumSet 都是 java.util 包中的私有类,所以我们甚至不能直接创建它。

您可以探索更多EnumSet 如何通过其源代码在内部实现(例如,参见here for the Java 9's version)。

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

【讨论】:

    【解决方案2】:

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

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

    这会显示所有可用的 EnumSet 子类的列表。

    【讨论】:

      【解决方案3】:

      这是 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);
      }
      

      【讨论】:

        【解决方案4】:

        用于枚举类型的专用 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);
        

        您找到了更多信息here...

        【讨论】:

          【解决方案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();
          ...
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-02-27
            • 2021-01-31
            • 2012-01-20
            • 1970-01-01
            • 2020-10-20
            • 2011-12-01
            • 2015-01-03
            • 2014-08-18
            相关资源
            最近更新 更多