java - 枚举是否比 public static final 常量更难维护?

标签 java performance enums constants maintainability

我最近与 friend 讨论枚举与公共(public)静态最终常量。我告诉他 public static final constants 比枚举更易于维护,有时速度更快(android 开发人员文档证实了这一点),也更方便。我还说过,使用枚举也会失去功能:

  1. 您不能扩展枚举。
  2. 您不能实例化枚举。

然后他说,如果您需要实例化或扩展枚举,则不应使用枚举。然后我回答说,这就是为什么我们应该只使用常量,因为它更易于维护;如果在项目中期我们需要实例化一个枚举或扩展它怎么办?然后我们将不得不改变一切。

为了说明我的观点而制作的枚举与常量示例:

public enum WeekDay {
/*
 * We will start at 1 for demonstration
 */
SUNDAY("Sunday", 1), MONDAY("Monday", 2), TUESDAY("Tuesday", 3), WEDNESDAY(
        "Wednesday", 4), THURSDAY("Thursday", 5), FRIDAY("Friday", 6), SATURDAY(
        "Saturday", 7);
/*
 * Notice we cannot do this...This is where enums fail.
 */
// LUNES("lunes",1), MARTES("martes",2);

private String dayName;
private int dayIndex;

private WeekDay(String dayName, int dayIndex) {
    this.dayName = dayName;
    this.dayIndex = dayIndex;
}

public String getDayName() {
    return dayName;
}

public void setDayName(String dayName) {
    this.dayName = dayName;
}

public int getDayIndex() {
    return dayIndex;
}

public void setDayIndex(int dayIndex) {
    this.dayIndex = dayIndex;
}

@Override
public String toString() {
    return this.dayName + ":  " + this.dayIndex;
}

如果我们还需要西类牙语工作日怎么办?枚举不足,因为您无法扩展它(您必须执行一些复制和粘贴操作)。

将枚举与此进行对比:

public class WeekDayClass {

    private int dayIndex;
    private String dayName;

    public WeekDayClass(int dayIndex, String dayName) {
        super();
        this.dayIndex = dayIndex;
        this.dayName = dayName;
    }

    public int getDayIndex() {
        return dayIndex;
    }

    public void setDayIndex(int dayIndex) {
        this.dayIndex = dayIndex;
    }

    public String getDayName() {
        return dayName;
    }

    public void setDayName(String dayName) {
        this.dayName = dayName;
    }

    @Override
    public String toString() {
        return this.dayName + ":  " + this.dayIndex;
    }

    abstract static class Constants {

    }


    public static void main(String[] args) {
        WeekDayClass init = new WeekDayClass(10, "I can init new days here");

    }
}

然后我可以扩展它并制作 AmericanWeekDays:

public class AmericanWeekDay extends WeekDayClass {
    public AmericanWeekDay(int dayIndex, String dayName) {
        super(dayIndex, dayName);
    }

    static class AmericanConstants extends Constants {
        public static final WeekDayClass SUNDAY = new WeekDayClass(1, "Sunday");
        public static final WeekDayClass MONDAY = new WeekDayClass(2, "Monday");
        /*
         * And so on...
         */
    }

}

或西类牙工作日:

 public class SpanishWeekDays extends WeekDayClass {

    public SpanishWeekDays(int dayIndex, String dayName) {
        super(dayIndex, dayName);
    }

    static class SpanishConstants extends Constants {
        public static final SpanishWeekDays LUNES = new SpanishWeekDays(2, "lunes");
        /*
         * And so on...
         */
    }

}

还要更进一步:

public class WeekDayClass {

    private int dayIndex;
    private String dayName;

    public WeekDayClass(int dayIndex, String dayName) {
        super();
        this.dayIndex = dayIndex;
        this.dayName = dayName;
    }

    public int getDayIndex() {
        return dayIndex;
    }

    public void setDayIndex(int dayIndex) {
        this.dayIndex = dayIndex;
    }

    public String getDayName() {
        return dayName;
    }

    public void setDayName(String dayName) {
        this.dayName = dayName;
    }

    @Override
    public String toString() {
        return this.dayName + ":  " + this.dayIndex;
    }

    static class AmericanConstants {
        /*
         * Insert Constants Here
         */

    }

    static class SpanishConstants {
        /*
         * Insert Constants Here
         */
    }

}

我知道对于枚举,您也许可以使用数据结构(列表)来解决这个问题,但为什么要费心呢?通过使用公共(public)静态常量,我获得了从基类的继承、更清晰的代码、可能更短的代码以及更容易的可维护性。

我还读到您可以使用枚举来更好地设计“输入参数”,但您也可以对公共(public)静态最终常量执行相同的操作,如上所示。

枚举的优点是可以在 switch 语句中使用,并且具有继承的枚举方法,如 values()。如果需要,也可以在“public static final constant”类中复制这些方法。除了开关之外,我看不到任何枚举优势。

总而言之,枚举真的比 public static final 常量更好吗?如果是这样,我哪里出错了?他们是我缺少的东西吗?

编辑: 您也不能在枚举中使用泛型。

最佳答案

枚举给你带来的好处远比你想象的要多,虽然有时需要常量,但这种情况可能是枚举的胜利。

首先,“英语工作日”和“西类牙语工作日”之间没有真正的区别,它们代表相同的值。因此,最好的解决方案是通过某种本地化方法独立于实际值是什么来转换为字符串。这些值不会随语言而改变,它们的表示会改变。

这完全可以通过枚举快速轻松地实现。就这样写吧(有点伪代码):

public enum Weekday {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    ...;

    public String toLocalizedString(Language l) {
        // interact with localization files
    }
}

您正在混淆外部表示和内部表示的概念。您的数据应尽可能同质,因为只有 一个 星期一。它可能被称为不同的东西,但它仍然是相同的值。

不过,枚举还可以免费为您带来很多好处,从长远来看,这会使您的代码更清晰、更易于维护。类型检查、== 比较和 switch 中的可用性只是少数,没有样板可言。

关于java - 枚举是否比 public static final 常量更难维护?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20558973/

相关文章:

java - 如何释放二维数组中的内存

javascript - 将 jQuery 对象存储在变量中是否不利?

c++ - 在 C++ 中通过 '::' 访问枚举值

java - 使用java使用正则表达式查找任意数字或重复的单词

java - 暂停测试执行直到应用程序空闲

java - 在 JDBC 中设置语句提取大小或使用 LIMIT 子句触发 SQL 查询有什么区别?

c# - string.IndexOf OrdinalIgnoreCase 与 CurrentCultureIgnoreCase 的性能

wpf - 首次使用 WPF 中的 WCF 非常慢

java - 访问枚举内的静态字段

java - 如何在注释中使用不同的枚举类型?