编写Java Enum的正确和错误方法

时间:2012-08-01 09:44:47

标签: java enums

最近,我发现了以下结构的代码:

接口

public interface Base<T> {

    public T fromValue(String v);

}

枚举实施

public enum AddressType implements Base<AddressType> {

    NotSpecified("Not Specified."),

    Physical("Physical"),

    Postal("Postal");

    private final String label; 

    private AddressType(String label) { 
        this.label = label; 
    } 

    public String getLabel() { 
        return this.label; 
    }

    @Override
    public AddressType fromValue(String v) {
        return valueOf(v);
    }
}

我的直接反应是,无法通过反序列化或反射来创建枚举实例,因此fromValue()应该是静态的。

我没有尝试开始辩论,但这是正确的吗?我已阅读Why would an Enum implement an interface,我完全同意所提供的答案,但上述示例无效。

我这样做是因为&#34;建筑师&#34;我不想接受我的回答,所以这是为了创造一个强有力的论据(用事实),为什么上述方法是好的/坏的。

3 个答案:

答案 0 :(得分:1)

您的Base界面未声明valueOf,并且fromValue方法确实已实施。我认为没有理由不编译这段代码。如果您指的是valueOf内的fromValue调用,则调用为每个枚举定义的静态方法。但是,我必须同意,它的设计是非常误导的,因为你需要一个任意的枚举成员才能调用fromValue并获得真正的成员。

另一方面,在我正在进行的项目中,我有几个实现通用接口的枚举。这是因为枚举是相关的,我希望能够统一对待它们的常见语义。

答案 1 :(得分:1)

在我看来,这种设计是错误的。为了使用valueFrom(),必须事先获得此枚举的实例。因此,它看起来像:

AddressType type = AddressType.Postal.valueFrom("Physical");

它有什么意义?

答案 2 :(得分:0)

您的Base界面似乎有其他用途(如果有的话)。

它可能意味着是一个String-to-T-converter,因为它从String生成一个T.如果enum实现了这个接口,那么AddressTypeConverter implements Base<AddressType>就完全错了(@ yegor256已经指出了原因)。因此,您可以保留枚举,并且可以在其AddressType.valueOf()方法中调用fromString() {。}}。

但是不要误解我的意思:实现接口的枚举并不是一种不好的做法,只是这种特殊用法是完全错误的。