假设我有两个不同的枚举
public enum SomeEnumClass {
private static final SomeEnumClass[] mValues = SomeEnumClass .values();
ONE(1), TWO(2), THREE(3);
}
public enum OtherEnumClass {
private static final OtherEnumClass[] mValues = OtherEnumClass .values();
Monday(1), Tuesday(2), Wednesday(3), Thrusday(4), Friday(5), Saturday(6), Sunday(7)
}
枚举的共同点是它们携带的数据类型(此处为int),并且它们的名称和可能值的数量不同。
对于每个枚举,我有几种实现方法,它们完全相同。例如:
public static OtherEnumClass getCell(int index)
{
if (index < OtherEnumClass .mValues.length )
{
return OtherEnumClass .mValues[index];
}
throw new IllegalArgumentException("Invalid " + OtherEnumClass .class.getSimpleName() + " value: " + index);
}
我试图找到一种避免重复这些方法的方法,就像我对抽象类一样。但到目前为止,我一无所获。
我们正在使用java 1.6,现在无法升级。任何帮助表示赞赏。感谢。
答案 0 :(得分:1)
你可以这样做:
public enum SomeEnumClass {
ONE, TWO, THREE;
}
public enum OtherEnumClass {
Monday, Tuesday, Wednesday, Thrusday, Friday, Saturday, Sunday
}
public static <E extends Enum> E getEnumItem(Class<E> type, int index){
E[] values = type.getEnumConstants();
if (index >= 0 && index < values.length){
return values[index];
} else {
throw new IllegalArgumentException("...");
}
}
public static void main(String[] args) {
System.out.println(getEnum(SomeEnumClass.class, 0));
System.out.println(getEnum(OtherEnumClass.class, 3));
System.out.println(getEnum(SomeEnumClass.class, 2));
System.out.println(getEnum(OtherEnumClass.class, 6));
}
打印:
ONE
Thrusday
THREE
Sunday
EDITED: 这与@dasblinkenlight
类似public enum SomeEnumClass {
ONE, TWO, THREE;
public static SomeEnumClass getCell(int index) {
return Utility.getEnumItem(SomeEnumClass.class, index);
}
}
public enum OtherEnumClass {
Monday, Tuesday, Wednesday, Thrusday, Friday, Saturday, Sunday;
public static OtherEnumClass getCell(int index) {
return Utility.getEnumItem(OtherEnumClass.class, index);
}
}
public static class Utility {
public static <E extends Enum> E getEnumItem(Class<E> type, int index) {
E[] values = type.getEnumConstants();
if (index >= 0 && index < values.length) {
return values[index];
} else {
throw new IllegalArgumentException("...");
}
}
}
public static void main(String[] args) {
System.out.println(Utility.getEnumItem(SomeEnumClass.class, 0));
System.out.println(Utility.getEnumItem(OtherEnumClass.class, 3));
System.out.println(Utility.getEnumItem(SomeEnumClass.class, 2));
System.out.println(Utility.getEnumItem(OtherEnumClass.class, 6));
}
答案 1 :(得分:1)
您可以将实现包装到通用帮助器类中,并在所有实现中使用它。不幸的是,你必须将调用复制到帮助器中; Java 8的默认方法解决了这个问题,但由于您仅限于Java 6,因此无法利用它们。
// Helper owns the static members that you used to add to your enums directly
class CellHelper<T> {
final T[] mValues;
final Class<T> cls;
// Helper needs Class<T> to work around type erasure
public CellHelper(T[] values, Class<T> c) {
mValues = values;
cls = c;
}
public T getCell(int index) {
if (index < mValues.length ) {
return mValues[index];
}
throw new IllegalArgumentException("Invalid " + cls.getSimpleName() + " value: " + index);
}
}
enum SomeEnumClass {
ONE(1), TWO(2), THREE(3);
SomeEnumClass(int n){}
// This variable hosts your static data, along with shared behavior
private static final CellHelper<SomeEnumClass> helper = new CellHelper(SomeEnumClass.values(), SomeEnumClass.class);
// Delegate the calls for shared functionality to the helper object
public static SomeEnumClass getCell(int i) {return helper.getCell(i);}
}
enum OtherEnumClass {
Monday(1), Tuesday(2), Wednesday(3), Thrusday(4), Friday(5), Saturday(6), Sunday(7);
OtherEnumClass(int n){}
private static final CellHelper<OtherEnumClass> helper = new CellHelper(OtherEnumClass.values(), OtherEnumClass.class);
public static OtherEnumClass getCell(int i) {return helper.getCell(i);}
}
答案 2 :(得分:0)
您可以使用界面:
public interface Indexed<E extends Enum> {
default public E getByIndex(int index) {
if (!this.getClass().isEnum()) {
//not implemented on enum, you can do as you like here
}
Enum<?>[] vals = (Enum<?>[]) this.getClass().getEnumConstants();
if (index < 0 || index >= vals.length) {
//illegal arg exception
}
return (E) vals[index];
}
}
然后在实施中:
public enum MyEnum implements Indexed<MyEnum> {
ONE,
TWO,
THREE,
;
}
另外需要注意的是,您可以只使用Enum#ordinal
。
这是一个仅限Java 8的解决方案,因为以前的Java版本中没有默认方法。此外,这有一些尴尬/不利的用法,因为它将是一个实例方法(尽管如果你愿意,你可以使它静止)。
对于早期版本,您需要一种提供类类型的方法,因为实际上没有一种方法可以为枚举提供它,您可以在其中使用David的答案。
答案 3 :(得分:0)
Helper课程非常有用。我们已经开始遇到坏工厂的问题,导致枚举依赖于订单 - 这是一个彻底的过程 -
现在我重构了所有枚举类,以便他们使用帮助程序和单个工厂。但是我通过以下方式改变了它的签名:
public static <E extends Enum<E> & IEnumWithValue> E factory(final E[] iConstants, int iValue) throws IllegalArgumentException
在我的枚举类中,我有一个成员定义为:
private static final MyEnum[] mValues = MyEnum.values();
这样,我不必在参数中传递枚举类型,而且我不必将调用乘以 values()或 class.getEnumConstants()