在上一篇博客里,我编写了一个UserType,实现了持久化自定义的enum类,其实那个例子中存在两个缺点。这两个缺点是关于如何正确使用enum以及generic的,她们已经和hibernate userType无关了,因此另起一个主题讨论。
在上一篇博客中,我的enum是这么写的:
public enum Status implements DescriptionID {
    ACTIVATED(5, "This object is activated"),  
    DEACTIVATED(9, "This object is deactivated");
    private Integer id;
    private String description;
    private static List<Status> list;
    static {
        list = new ArrayList<Status>(2);
        list.add(ACTIVATED);
        list.add(DEACTIVATED);
    }
    private Status(int statusNr, String description) {
        this.id = statusNr;
        this.description = description;
    }
    public String getDescription() {
        return this.description;
    }
    public Integer getId() {
        return id;
    }
    public static List<Status> getAll() {
        return list;
    }
    public static Status findById(Integer id) {
        for (Status status : getAll()) {
            if (id == status.getId()) {
                return status;
            }
        }
        return null;
    }
}
其中两个static方法是为了方便使用。
缺点一:
         所有的enum实例必须手动纳入list集合中。
解决方法: 
  
        解决方法非常简单,是用Class类提供的方法getEnumConstants(), 代码如下:
    public static List<Status> getAll() {
        return Arrays.asList(Status.class.getEnumConstants());
    }
我个人比较讨厌数组,因此这里特意将数组转换成List。如果你们不介意使用数组的话,getAll()方法完全可以省略。
缺点二: 
             
findById(Integer id) 方法名并不贴切,叫getEnumById(Integer id)会更好些。另外一模一样的方法必须在每一个enum类中重复编写,如果某个地方需要改动,那就需要改动所有相关的enum类,这是一个很明显的bad smell。
解决方法:
        编写一个util类,将逻辑转移到util类中,getEnumById(Integer id)方法调用util类中的相关方法,代码如下:
    public static Status getEnumById(Integer id) {
        return EnumUtils.getEnum(Status.class, id);
    }
public class EnumUtils {
    public static <I extends DescriptionID> I getEnum(Class<I> type, int id) {
        I[] types = type.getEnumConstants();
        for (I t : types) {
            if (t.getId() == id)
                return t;
        }
        return null;
    }
}
这里getEnum(Class<I> type, int id)方法利用Java 5的新特性generic,利用给定的Class和enum id,返回对应的enum实例。这样处理好处很明显,获取enum实例的逻辑代码只存在与util类中,日后修改十分方便。
相关内容请参阅
我写的《Hibernate 3和Java Persistence API 程序开发从入门到精通》一书。
声明:本文版权归作者所有,如需转载请注明出处。