我似乎多次遇到过这个问题,我想问问社区我是否只是在找错树。基本上我的问题可以归结为:如果我有一个值很重要的枚举(在 Java 中),我应该使用枚举还是有更好的方法,如果我确实使用枚举,那么是反转查找的最佳方法吗?
这是一个例子。假设我想创建一个代表特定月份和年份的 bean。我可能会创建如下内容:
public interface MonthAndYear {
Month getMonth();
void setMonth(Month month);
int getYear();
void setYear(int year);
}
在这里,我将我的月份存储为一个名为 Month 的单独类,以便它是类型安全的。如果我只是输入 int,那么任何人都可以将 13 或 5,643 或 -100 作为数字传递,并且无法在编译时检查它。我限制他们放一个月,我将作为枚举实施:
public enum Month {
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER;
}
现在假设我有一些我想写入的后端数据库,它只接受整数形式。那么执行此操作的标准方法似乎是:
public enum Month {
JANUARY(1),
FEBRUARY(2),
MARCH(3),
APRIL(4),
MAY(5),
JUNE(6),
JULY(7),
AUGUST(8),
SEPTEMBER(9),
OCTOBER(10),
NOVEMBER(11),
DECEMBER(12);
private int monthNum;
public Month(int monthNum) {
this.monthNum = monthNum;
}
public getMonthNum() {
return monthNum;
}
}
相当简单,但是如果我想从数据库中读取这些值并写入它们会发生什么?我可以使用枚举中的 case 语句来实现一个静态函数,该语句接受一个 int 并返回相应的 Month 对象。但这意味着如果我改变了任何东西,那么我将不得不改变这个函数以及构造函数参数——在两个地方改变。这就是我一直在做的事情。首先,我创建了一个可逆地图类,如下所示:
public class ReversibleHashMap<K,V> extends java.util.HashMap<K,V> {
private java.util.HashMap<V,K> reverseMap;
public ReversibleHashMap() {
super();
reverseMap = new java.util.HashMap<V,K>();
}
@Override
public V put(K k, V v) {
reverseMap.put(v, k);
return super.put(k,v);
}
public K reverseGet(V v) {
return reverseMap.get(v);
}
}
然后我在我的枚举而不是构造函数方法中实现了这个:
public enum Month {
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER;
private static ReversibleHashMap<java.lang.Integer,Month> monthNumMap;
static {
monthNumMap = new ReversibleHashMap<java.lang.Integer,Month>();
monthNumMap.put(new java.lang.Integer(1),JANUARY);
monthNumMap.put(new java.lang.Integer(2),FEBRUARY);
monthNumMap.put(new java.lang.Integer(3),MARCH);
monthNumMap.put(new java.lang.Integer(4),APRIL);
monthNumMap.put(new java.lang.Integer(5),MAY);
monthNumMap.put(new java.lang.Integer(6),JUNE);
monthNumMap.put(new java.lang.Integer(7),JULY);
monthNumMap.put(new java.lang.Integer(8),AUGUST);
monthNumMap.put(new java.lang.Integer(9),SEPTEMBER);
monthNumMap.put(new java.lang.Integer(10),OCTOBER);
monthNumMap.put(new java.lang.Integer(11),NOVEMBER);
monthNumMap.put(new java.lang.Integer(12),DECEMBER);
}
public int getMonthNum() {
return monthNumMap.reverseGet(this);
}
public static Month fromInt(int monthNum) {
return monthNumMap.get(new java.lang.Integer(monthNum));
}
}
现在这做了我想要的一切,但它看起来仍然是错误的。人们向我建议“如果枚举具有有意义的内部值,则应该改用常量”。但是,我不知道这种方法如何为我提供我正在寻找的类型安全性。不过,我开发的方式似乎过于复杂。有没有一些标准的方法来做这种事情?
PS:我知道政府增加新月份的可能性......不太可能,但请考虑更大的图景 - 枚举有很多用途。