5

I see that EnumSet.of() returns an instance of an object of the type EnumSet. But I am not able to figure out which class actually implements this abstract class? How can you get an instance of the abstract type EnumSet, when you have not subclassed it?

Foo
  • 4,206
  • 10
  • 39
  • 54
  • 1
    Why don't you just look in the implementation of `EnumSet.of()`? – Max Vollmer Apr 24 '18 at 17:15
  • @azurefrog: You cannot instantiate an abstract class, but you can get an instance of the abstract type. For example myAbstractClass abs= new myImplementation(); Here abs is an instance of the type myAbstractClass . – Foo Apr 24 '18 at 17:22
  • try `System.out.println(EnumSet.noneOf(RetentionPolicy.class).getClass());` – Peter Lawrey Apr 24 '18 at 17:37

5 Answers5

6

Here is are 2 classes in java which extends EnumSet

1. RegularEnumSet
2. JumboEnumSet

You can create the instance using EnumSet's static methods like EnumSet#noneOf, EnumSet#allOf etc. Which actually returns the instance of RegularEnumSet or JumboEnumSet depending on the condition. EnumSet#of internally calls EnumSet#noneOf.Please refer the below code from Java to see how EnumSet#noneOf works

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);
}
Amit Bera
  • 7,075
  • 1
  • 19
  • 42
5

You do not directly create instances of EnumSet. This is done by the static factory methods, such as:

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

The resulting sets are mutable, i.e., you can do:

EnumSet<Demo> set = EnumSet.noneOf(Demo.class);  // start with an empty set
...
set.add(Demo.YES);
set.remove(Demo.NO);
...
set.clear();
...
Dirk
  • 30,623
  • 8
  • 82
  • 102
0

A specialized Set implementation for use with enum types. All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created.

You can't create a instance if EnumSet! However also you don't need to extend it, for it's purpose there is a factory method to create a Set from specified elements:

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

It creates an object for you. Often EnumSets are used for combining effects, whether it's text styles e.g. BOLD and UNDERLINE or with colors...

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

You found additional information here...

0x1C1B
  • 1,204
  • 11
  • 40
0

To find this information, you could look at all the code, or print out the getClass() of the object returned as a sample but a simpler way is to use your IDE.

Navigate to EnumSet and click the icon showing the implementations

implementations of EnumSet

This shows you a list of all the available sub-classes of EnumSet available.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

The other answers already answered what are the concrete subclasses of EnumSet that actually implement the abstract class EnumSet. I will attempt to clarify how we can get an instance of the abstract type EnumSet, when we have not subclassed it.

Observe that EnumSet does not have a constructor, so it is not intended to be used like a normal class:

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

Rather, to create an EnumSet, we use one of its static initializers (such as of). These initializers will internally create an object of type either JumboEnumSet (if the number of enum constants is large) or RegularEnumSet (otherwise) and return the reference of that object.

Since JumboEnumSet and RegularEnumSet are both subclasses of EnumSet, they can be assigned to a variable of type EnumSet (this is known as widening reference conversion).

The beauty of this is that when we use the variable of type EnumSet, we do not have to know which concrete implementation we are using. In fact, both JumboEnumSet and RegularEnumSet are both private class in the package java.util so we can't even create it directly.

You can explore more how EnumSet is implemented internally through its source (see, for instance here for the Java 9's version).

Another example of commonly use type in Java that is not actually a concrete class is Stream. Stream is actually an interface.

wto
  • 212
  • 1
  • 7