Phaellow
Phaellow

Reputation: 73

Get values of generic enum that implements an interface

I have the following interface:

public interface GenericMethods {
  public String getString();
}

With this interface, I implemented this enum:

public enum SpecificEnum implements GenericMethods {
  A("NOT"), B("RELATED"), C("TEXT");

  SpecificEnum(String string) {
    this.string = string;
  }

  private String string;
  
  @Override
  public String getString() {
    return this.string;
  }
}

Now, I want to be able to call a function with the parameter SpecificEnum.class and be able to call the values() function on that parameter, as well as the interface methods on the returned array elements. Something like this:

class Main {
  public static void main(String[] args) {
    for (GenericMethods gm : getEnums(SpecificEnum.class)) {
      System.out.printf(gm.getString());
    }
  }

  public static T[]<T extends GenericMethods> getEnums(Class<T> enum1) {
    enum1.values();
  }
}

However, after searching a lot, I haven't come across a case using generics with enums that implement interfaces at the same time. I also thinkered a lot with the generic types but I can't find the right syntax to be able to call values() on a generic enum class. The main objective is to have multiple related enums be managed all in the same way.

Upvotes: 7

Views: 4446

Answers (2)

Pshemo
Pshemo

Reputation: 124225

I suspect you may be looking for something like:

public static <T extends Enum<T> & GenericMethods> T[] getEnums(Class<T> enum1) {
    return enum1.getEnumConstants();
}

public static void main(String[] args) {
    for (GenericMethods gm : getEnums(SpecificEnum.class)) {
        System.out.println(gm.getString());
    }
}

Results:
(demo: https://ideone.com/v6on2p)

NOT
RELATED
TEXT

Changes:

  • moved <T extends GenericMethods> before return type since only there generic method can declare its generic type.
  • modified generic type to <T extends Enum<T> & GenericMethods> to force T to also be subtype of some Enum aside from implementing GenericMethods
  • used getEnumConstants() instead of values() as we are using Class, not enum type.

Upvotes: 9

Andreas
Andreas

Reputation: 159086

Call getEnumConstants() on the Class object. As the javadoc says:

Returns the elements of this enum class or null if this Class object does not represent an enum type.

The signature of your method is wrong too. Here is how to write it:

public static <T extends GenericMethods> T[] getEnums(Class<T> enumClass) {
    return enumClass.getEnumConstants();
}

Of course, it might return null, because there is no guarantee that the Class object is an enum class. E.g. with the following class, getEnums(Foo.class) returns null:

public class Foo implements GenericMethods {
    @Override
    public String getString() {
        return "Boo!!";
    }
}

To make sure that the Class is an enum class, change the method to:

public static <T extends Enum<T> & GenericMethods> T[] getEnums(Class<T> enumClass) {
    return enumClass.getEnumConstants();
}

Tests

getEnums(Foo.class); // fails to compile
SpecificEnum[] enums = getEnums(SpecificEnum.class);
System.out.println(Arrays.toString(enums));

Output

[A, B, C]

Upvotes: 2

Related Questions