0

I have an enum containing reference to a class of enum like so:

enum Animal { 
  DOG(DayOfWeek.class),
  CAT(Month.class);

  public Class<? extends Enum> clazz;

  Animal(Class<? extends Enum> c) {
    this.clazz = c;
  }

  public String getValuesConcat() {
    String allValues = "";

    // The following line doesn't compile
    for (Object enumValue : EnumSet.allOf(clazz)) {
      allValues += " " + enumValue.toString();
    }

    return allValues;
  }
}

I couldn't figure out a way to store Enum class so that I can get the list of values from it later. Any clues?

Artem
  • 7,275
  • 15
  • 57
  • 97
  • 1
    You code compiles for me, and `Animal.DOG.getValuesConcat()` returns `MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY`. What error do you get? – tgdavies Feb 23 '21 at 04:40
  • 1
    Are you going to need the `clazz` member later? Or is it just to get the values? – Axel Feb 23 '21 at 04:56
  • 1
    FYI: This Question is derived from: [*Variable of type of enum class*](https://stackoverflow.com/q/66309963/642706). – Basil Bourque Feb 23 '21 at 04:57

3 Answers3

2

Rather than using an EnumSet, I think it's cleaner to use Class#getEnumConstants. This returns an array of your enum objects.

            for (Enum enumValue : clazz.getEnumConstants()) {
                allValues += " " + enumValue.name();
            }

Be aware that this code will NPE if clazz is not an Enum.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
tgdavies
  • 10,307
  • 4
  • 35
  • 40
1

You can extend the correct Answer by tgdavies to get an unmodifiable Set of your enum objects.

Pass the array of enum objects returned by Class#getEnumConstants to the Set.of method.

Here is a code example equivalent to your Set.of( Animal.CAT.clazz.getEnumConstants() ) ;.

Set< Month > months = Set.of( Month.class.getEnumConstants() ) ;  // Pass array of enum objects to `Set.of` to produce an unmodifiable set.
        
System.out.println( "months: " + months ) ;

See this code run live at IdeOne.com.

months: [JANUARY, MAY, NOVEMBER, DECEMBER, MARCH, OCTOBER, JUNE, APRIL, AUGUST, JULY, SEPTEMBER, FEBRUARY]

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

I totally overlooked that you need another enum's values.

Since the enum constructor is private anyway, why make your life hard by passing a Class object? Just pass the values instead. This should work as long as your enum contains at least one value:

enum Animal {
    DOG(DayOfWeek.values()),
    CAT(Month.values());

    public final Class<? extends Enum<?>> clazz;
    private final Enum<?>[] values;

    <T extends Enum<T>> Animal(T[] values) {
        this.clazz = (Class<? extends Enum<?>>) values[0].getClass();
        this.values = values;
    }

    public String getValuesConcat() {
        return Arrays.stream(values).map(Enum::name).collect(Collectors.joining(" "));
    }
}
Axel
  • 13,939
  • 5
  • 50
  • 79