【问题标题】:The right and wrong approach to writing Java Enums编写 Java 枚举的正确和错误方法
【发布时间】:2012-08-01 09:44:46
【问题描述】:

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

接口

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,我完全同意所提供的答案,但上述示例无效。

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

【问题讨论】:

  • 除了枚举,还有其他实现接口的类吗?
  • @Edwin Dalorzo,不。只有接口。

标签: java enums


【解决方案1】:

你的Base 接口没有声明valueOf 并且确实实现了fromValue 方法。我看不出为什么这段代码不应该编译。如果您指的是fromValue 内部的valueOf 调用,那是对为每个枚举定义的静态方法的调用。不过,我不得不同意,它的设计是非常错误的,因为您需要枚举的任意成员才能调用 fromValue 并获取真正的成员。

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

【讨论】:

  • 太好了,谢谢...我混合了fromValuevalueOf,但另一个论点仍然成立。
【解决方案2】:

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

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

这有什么意义?

【讨论】:

    【解决方案3】:

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

    它可能是一个 String-to-T-converter,因为它从 String 生成一个 T。如果enum 实现了这个接口,那么它就是错误的(@yegor256 已经指出了原因)。所以你可以保留枚举,你可以有一些AddressTypeConverter implements Base&lt;AddressType&gt; 在其fromString() 方法中调用AddressType.valueOf()

    但不要误会我的意思:实现接口的枚举并不是一个坏习惯,只是这种特殊用法是完全错误的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 2013-09-23
      相关资源
      最近更新 更多