Reputation: 73
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
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:
<T extends GenericMethods>
before return type since only there generic method can declare its generic type.<T extends Enum<T> & GenericMethods>
to force T to also be subtype of some Enum aside from implementing GenericMethodsgetEnumConstants()
instead of values()
as we are using Class
, not enum
type.Upvotes: 9
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