Reputation: 9720
I've read some topics about this, but still can't figure out how I can do the thing I want to do:
I have a number of enums that extend a particular interface (HasCode
), which declares one function, code()
, which returns the int code of this enum. All the extending enums have private int
vars and parameters to their constructors (etc).
I would like to have a function that would accept an enum class as a parameter and return a hashtable of the names of the enum's values and the int values of those enum values.
Here is an example of my enums:
public enum InvoiceStatuses implements HasCode<InvoiceStatuses> {
NONE(0), REQUESTED(10), RECEIVED(20), APPROVED(30), PAID(40), ERROR(-100);
private int code;
private InvoiceStatuses(int a) {
code = a;
}
public int code() {
return code;
}
public static InvoiceStatuses invoiceStatusByCode(int aCode) {
switch (aCode) {
case 0:
return NONE;
case 10:
return REQUESTED;
case 20:
return RECEIVED;
case 30:
return APPROVED;
case 40:
return PAID;
}
return ERROR;
}
public int compare(InvoiceStatuses anotherLevel) {
if (code > anotherLevel.code()) {
return 1;
} else if (code < anotherLevel.code()) {
return -1;
}
return 0;
}
@Override
public InvoiceStatuses[] enumValues() {
return InvoiceStatuses.values();
}
}
HasCode:
public interface HasCode <T extends Enum<?>>{
public int code();
public T[] enumValues();
}
And here is the class with that magic function (that iterates over the values of the enum)
import java.util.Hashtable;
import java.util.LinkedList;
public class SelectFromEnum<T extends Enum<?>> {
public SelectFromEnum() {}
public Hashtable<String, String> createSelect(HasCode<T> anEnum) throws Exception{
if (! (anEnum instanceof Enum)) {
throw new Exception ("I only accept enums...");
}
T[] values = anEnum.enumValues();
for (T value : values) {
System.out.println(value.name() + " __ " + ((HasCode)value).code());
}
return null;
}
}
What i don't like about this:
1) I have to pass a concrete enum member as the parameter to the createSelect
function, and I would like to pass the (enum).class;
2) I would like the parameter of the createSelect
to specify that it is an Enum that extends a given interface, but i can't quite figure out how to do that.
Update:
In accordance with Ingo Kegel's comment I modified the SelectFromEnum
the following way (see below), and now value.name()
doesn't compile...
import java.util.Hashtable;
import java.util.LinkedList;
public class SelectFromEnum<C extends HasCode> {
public SelectFromEnum() {
}
public Hashtable<String, String> createSelect(Class<C> anEnum) throws Exception {
if (!anEnum.isEnum()) {
throw new Exception("I only accept enums...");
}
C[] values = anEnum.getEnumConstants();
for (C value : values) {
System.out.println(value.name() + " __ " + value.code());
}
return null;
}
}
I can add name()
to the HasCode
interface, but is there a way to persuade the compiler that value
is an enum member?
Upvotes: 2
Views: 5236
Reputation: 11818
Not sure why you're using a type parameter to HasCode, simply implement the interface on the enums you want to use. I suspect you were trying to use it as a way of restricting implementations to enums, but that shouldn't be necessary. You shouldn't care what implements an interface.
Try it another way
createSelect(EnumSet.allOf(InvoiceStatus.class));
public Hashtable createSelect(EnumSet<? extends HasCode> enums) {
for (HasCode c : enums) {
c.code();
}
}
You're guaranteed that enums will be a Set
of Enum
values, if that matters to you. Also far simpler to understand, and you don't directly need an instance of enum.
Upvotes: 1
Reputation: 47995
You don't have to use an instance of the enum. You can pass the class and use Class#isEnum
and Class#getEnumConstants()
.
Edit
You can cast to objects returned by Class#getEnumConstants()
to Enum
and your code should look like this:
public LinkedList createSelectFrom(Class anEnum) throws Exception {
if (!anEnum.isEnum()) {
throw new Exception("I only accept enums...");
}
Object[] values = anEnum.getEnumConstants();
for (Object value : values) {
System.out.println(((Enum)value).name() + " __ " + ((HasCode) value).code());
}
}
Upvotes: 8